mirror of https://github.com/mpv-player/mpv
audio: fix initial audio PTS
Commit 5e25a3d2
broke handling of the initial frame (the one decoded
with initial_audio_decode()). It didn't update the pts_offset field,
leading to a shift in timestamps by one audio frame.
Fix by calling the actual decode function in a single place. This
requires slightly more changes than what would be necessary to fix the
bug, but it also somewhat simplifies the data flow.
This commit is contained in:
parent
1a522f2976
commit
4cabd08e8a
|
@ -153,23 +153,33 @@ void audio_uninit(struct dec_audio *d_audio)
|
||||||
MP_VERBOSE(d_audio, "Uninit audio filters...\n");
|
MP_VERBOSE(d_audio, "Uninit audio filters...\n");
|
||||||
af_destroy(d_audio->afilter);
|
af_destroy(d_audio->afilter);
|
||||||
uninit_decoder(d_audio);
|
uninit_decoder(d_audio);
|
||||||
|
talloc_free(d_audio->waiting);
|
||||||
talloc_free(d_audio);
|
talloc_free(d_audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int decode_new_frame(struct dec_audio *da)
|
||||||
|
{
|
||||||
|
while (!da->waiting) {
|
||||||
|
int ret = da->ad_driver->decode_packet(da, &da->waiting);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (da->waiting) {
|
||||||
|
da->pts_offset += da->waiting->samples;
|
||||||
|
da->decode_format = *da->waiting;
|
||||||
|
mp_audio_set_null_data(&da->decode_format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mp_audio_config_valid(da->waiting) ? AD_OK : AD_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Decode packets until we know the audio format. Then reinit the buffer.
|
/* Decode packets until we know the audio format. Then reinit the buffer.
|
||||||
* Returns AD_OK on success, negative AD_* code otherwise.
|
* Returns AD_OK on success, negative AD_* code otherwise.
|
||||||
* Also returns AD_OK if already initialized (and does nothing).
|
* Also returns AD_OK if already initialized (and does nothing).
|
||||||
*/
|
*/
|
||||||
int initial_audio_decode(struct dec_audio *da)
|
int initial_audio_decode(struct dec_audio *da)
|
||||||
{
|
{
|
||||||
while (!da->waiting) {
|
return decode_new_frame(da);
|
||||||
int ret = da->ad_driver->decode_packet(da, &da->waiting);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
talloc_steal(da, da->waiting);
|
|
||||||
da->decode_format = *da->waiting;
|
|
||||||
return mp_audio_config_valid(da->waiting) ? AD_OK : AD_ERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool copy_output(struct af_stream *afs, struct mp_audio_buffer *outbuf,
|
static bool copy_output(struct af_stream *afs, struct mp_audio_buffer *outbuf,
|
||||||
|
@ -208,31 +218,22 @@ int audio_decode(struct dec_audio *da, struct mp_audio_buffer *outbuf,
|
||||||
if (copy_output(afs, outbuf, minsamples, false))
|
if (copy_output(afs, outbuf, minsamples, false))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
struct mp_audio *mpa = da->waiting;
|
res = decode_new_frame(da);
|
||||||
da->waiting = NULL;
|
if (res < 0) {
|
||||||
if (!mpa) {
|
// drain filters first (especially for true EOF case)
|
||||||
res = da->ad_driver->decode_packet(da, &mpa);
|
copy_output(afs, outbuf, minsamples, true);
|
||||||
if (res < 0) {
|
break;
|
||||||
// drain filters first (especially for true EOF case)
|
|
||||||
copy_output(afs, outbuf, minsamples, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!mpa)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
da->pts_offset += mpa->samples;
|
|
||||||
da->decode_format = *mpa;
|
|
||||||
mp_audio_set_null_data(&da->decode_format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// On format change, make sure to drain the filter chain.
|
// On format change, make sure to drain the filter chain.
|
||||||
if (!mp_audio_config_equals(&afs->input, mpa)) {
|
if (!mp_audio_config_equals(&afs->input, da->waiting)) {
|
||||||
da->waiting = talloc_steal(da, mpa);
|
|
||||||
copy_output(afs, outbuf, minsamples, true);
|
copy_output(afs, outbuf, minsamples, true);
|
||||||
res = AD_NEW_FMT;
|
res = AD_NEW_FMT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mp_audio *mpa = da->waiting;
|
||||||
|
da->waiting = NULL;
|
||||||
if (af_filter_frame(afs, mpa) < 0)
|
if (af_filter_frame(afs, mpa) < 0)
|
||||||
return AD_ERR;
|
return AD_ERR;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue