diff --git a/audio/out/ao_avfoundation.m b/audio/out/ao_avfoundation.m index e30d4c15a47f3..581fc788bda10 100644 --- a/audio/out/ao_avfoundation.m +++ b/audio/out/ao_avfoundation.m @@ -65,11 +65,14 @@ static void feed(struct ao *ao) CMBlockBufferRef block_buffer = NULL; CMSampleBufferRef sample_buffer = NULL; - if (p->end_time_mp == -1) { - p->end_time_mp = mp_time_ns(); - } - if (p->end_time_av == -1) { - p->end_time_av = CMTimeGetNanoseconds([p->synchronizer currentTime]); + int64_t time_mp = mp_time_ns(); + int64_t time_av = CMTimeGetNanoseconds([p->synchronizer currentTime]); + int64_t end_time_mp = p->end_time_mp == -1 ? time_mp : p->end_time_mp; + int64_t end_time_av = p->end_time_av == -1 ? time_av : p->end_time_av; + int64_t diff = (time_mp - time_av) - (end_time_mp - end_time_av); + if (diff > 1000000 || diff < -1000000) { + MP_WARN(ao, "timestamps mismatch; restarting"); + goto error; } int request_sample_count = ao->samplerate / 10; // 1/10 samplerate may be a good number @@ -94,7 +97,7 @@ static void feed(struct ao *ao) goto error; } - int real_sample_count = ao_read_data_nonblocking(ao, data, request_sample_count, p->end_time_mp); + int real_sample_count = ao_read_data_nonblocking(ao, data, request_sample_count, end_time_mp); if (real_sample_count == 0) { CFRelease(block_buffer); block_buffer = NULL; @@ -104,7 +107,7 @@ static void feed(struct ao *ao) CMSampleTimingInfo sample_timing_into[] = {(CMSampleTimingInfo) { .duration = CMTimeMake(1, ao->samplerate), - .presentationTimeStamp = CMTimeFromNanoseconds(p->end_time_av), + .presentationTimeStamp = CMTimeFromNanoseconds(end_time_av), .decodeTimeStamp = kCMTimeInvalid }}; size_t sample_size_array[] = {ao->sstride}; @@ -130,8 +133,8 @@ static void feed(struct ao *ao) sample_buffer = NULL; int64_t delta = CMTimeGetNanoseconds(CMTimeMake(real_sample_count, ao->samplerate)); - p->end_time_mp += delta; - p->end_time_av += delta; + p->end_time_mp = end_time_mp + delta; + p->end_time_av = end_time_av + delta; return;