Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "ao_coreaudio: switch to ao_read_data_nonblocking()" #13902

Merged
merged 1 commit into from
Apr 17, 2024

Conversation

m154k1
Copy link
Contributor

@m154k1 m154k1 commented Apr 16, 2024

Fixes #13880

Copy link

Download the artifacts for this pull request:

Windows
macOS

@Dudemanguy
Copy link
Member

Maybe 0341a6f needs to be reverted too?

@sfan5
Copy link
Member

sfan5 commented Apr 16, 2024

Maybe 0341a6f needs to be reverted too?

No, the blocking function does not guarantee that ret_samples == samples either.

@kasper93
Copy link
Contributor

Is it possible to do the same for ao_avfoundation?

diff --git a/audio/out/ao_avfoundation.m b/audio/out/ao_avfoundation.m
index 7654916519..61bf39620e 100644
--- a/audio/out/ao_avfoundation.m
+++ b/audio/out/ao_avfoundation.m
@@ -76,12 +76,7 @@ static void feed(struct ao *ao)
     int64_t cur_time_mp = mp_time_ns();
     int64_t end_time_av = MPMAX(p->end_time_av, cur_time_av);
     int64_t time_delta = CMTimeGetNanoseconds(CMTimeMake(request_sample_count, samplerate));
-    int real_sample_count = ao_read_data_nonblocking(ao, data, request_sample_count, end_time_av - cur_time_av + cur_time_mp + time_delta);
-    if (real_sample_count == 0) {
-        // avoid spinning by blocking the thread
-        mp_sleep_ns(10000000);
-        goto finish;
-    }
+    int real_sample_count = ao_read_data(ao, data, request_sample_count, end_time_av - cur_time_av + cur_time_mp + time_delta);

     if ((err = CMBlockBufferCreateWithMemoryBlock(
         NULL,

@Akemi
Copy link
Member

Akemi commented Apr 17, 2024

@ruihe774 see @kasper93 comment above.

@ruihe774
Copy link
Contributor

Is it possible to do the same for ao_avfoundation?

diff --git a/audio/out/ao_avfoundation.m b/audio/out/ao_avfoundation.m
index 7654916519..61bf39620e 100644
--- a/audio/out/ao_avfoundation.m
+++ b/audio/out/ao_avfoundation.m
@@ -76,12 +76,7 @@ static void feed(struct ao *ao)
     int64_t cur_time_mp = mp_time_ns();
     int64_t end_time_av = MPMAX(p->end_time_av, cur_time_av);
     int64_t time_delta = CMTimeGetNanoseconds(CMTimeMake(request_sample_count, samplerate));
-    int real_sample_count = ao_read_data_nonblocking(ao, data, request_sample_count, end_time_av - cur_time_av + cur_time_mp + time_delta);
-    if (real_sample_count == 0) {
-        // avoid spinning by blocking the thread
-        mp_sleep_ns(10000000);
-        goto finish;
-    }
+    int real_sample_count = ao_read_data(ao, data, request_sample_count, end_time_av - cur_time_av + cur_time_mp + time_delta);

     if ((err = CMBlockBufferCreateWithMemoryBlock(
         NULL,

@kasper93 avfoundation can well handle audio buffer of variable length.

@Akemi Akemi added this to the Release v0.38.0 milestone Apr 17, 2024
@@ -89,7 +89,7 @@ static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags,

int64_t end = mp_time_ns();
end += p->hw_latency_ns + ca_get_latency(ts) + ca_frames_to_ns(ao, frames);
int samples = ao_read_data_nonblocking(ao, planes, frames, end);
int samples = ao_read_data(ao, planes, frames, end);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should not use samples returned from ao_read_data, which may be less than requested. The original implementation did not use it and always submit buffers of requested length to CoreAudio. CoreAudio expect the buffer length be equal to requested.

@sfan5
Copy link
Member

sfan5 commented Apr 17, 2024

@kasper93 avfoundation can well handle audio buffer of variable length.

The point is that sleeping 10ms when no samples are returned makes no sense. You can as well just use the blocking variant.

@kasper93
Copy link
Contributor

kasper93 commented Apr 17, 2024

@kasper93 avfoundation can well handle audio buffer of variable length.

That's cool. Let me rephrase my question. Could we remove this terrible hack of blocking the audio thread for 10 ms, by all and any means necessary?

@ruihe774
Copy link
Contributor

ruihe774 commented Apr 17, 2024

I don't think "sleeping 10ms" and "blocking variant" are the same thing. ao_read_data, the "blocking variant", does not block when "no samples are returned". It only blocks on mutex contention. We still need to sleep for "no samples are returned" even if ao_read_data is used.

FWIW, #11955 (comment), #11955 (comment)

@sfan5 sfan5 merged commit 7a8a92b into mpv-player:master Apr 17, 2024
14 checks passed
@sfan5
Copy link
Member

sfan5 commented Apr 17, 2024

I don't think "sleeping 10ms" and "blocking variant" are the same thing. ao_read_data, the "blocking variant", does not block when "no samples are returned". It only blocks on mutex contention.

I assumed that the sleep was added after the author noticed that it would spuriously return zero (usually on mutex contention, like you said). If this isn't the case then that doesn't apply ofc.
I haven't investigated closely but if the lack of samples instead happens near EOF it sounds like the core is maybe not pausing the AO early enough?

@ruihe774
Copy link
Contributor

ruihe774 commented Apr 17, 2024

I don't think "sleeping 10ms" and "blocking variant" are the same thing. ao_read_data, the "blocking variant", does not block when "no samples are returned". It only blocks on mutex contention.

I assumed that the sleep was added after the author noticed that it would spuriously return zero (usually on mutex contention, like you said). If this isn't the case then that doesn't apply ofc. I haven't investigated closely but if the lack of samples instead happens near EOF it sounds like the core is maybe not pausing the AO early enough?

The core does not stop AO until EOF. In fact, there is no API for core to tell pull-based AO to "stop requesting data but continue playing enqueued data". Some AO, like pipewire, will starve and spin near EOF; but because pipewire usually has very short device buffer (1024 samples usually), it will not spin too many times. This is not the case for avfoundation, which can be starving for more than 1 second near EOF.

@ruihe774
Copy link
Contributor

@sfan5 why you've merged it? I have a ongoing review #13902 (comment)

@sfan5
Copy link
Member

sfan5 commented Apr 17, 2024

The core does not stop AO until EOF. In fact, there is no API for core to tell pull-based AO to "stop requesting data but continue playing enqueued data". Some AO, like pipewire, will starve and spin near EOF; but because pipewire usually has very short device buffer (1024 samples usually), it will not spin too many times.

I see. Maybe that'd be a good thing to address in the future. Just sleeping in the ao thread feels like a dirty fix.

@sfan5 why you've merged it? I have a ongoing review #13902 (comment)

We decided on IRC that we are okay with merging the revert since OP confirmed that it helps their case.
The other change has been there longer (0341a6f) and we're not aware of it causing issues yet. So that can be solved afterwards.

@Akemi
Copy link
Member

Akemi commented Apr 17, 2024

it was actually because of me. i didn't see your comment and i felt like reverting to the state before would be reasonable. we were talking about the release and what is blocking it on irc and decided to merge it.

20:43 der_richter from the comments on the issue it seems to fix the issue. can't really confirm since i didn't encounter it.
20:45 if you are fine with it, i would merge the revert commit for now. since we don't really have anyone who is well versed with the coreaudio stuff, i doubt we could get a better solution in a timely fashion? and if we do we can still merge another fix.

i am still very much interested in a proper solution, if possible.

@ruihe774
Copy link
Contributor

We decided on IRC that we are okay with merging the revert since OP confirmed that it helps their case. The other change has been there longer (0341a6f) and we're not aware of it causing issues yet. So that can be solved afterwards.

0341a6f is a hacky fix for ae908a7 (see #12643 (comment)). Since we've reverted ae908a7, 0341a6f is no longer necessary. Giving there are no issues reported for it, I'm OK with current solution.

@Akemi
Copy link
Member

Akemi commented Apr 17, 2024

we actually have a problem with 0341a6f, this one #13348, and i was contemplating of reverting it too.

should we revert it too or do you think there is a better way of handling it @ruihe774?

@ruihe774
Copy link
Contributor

we actually have a problem with 0341a6f, this one #13348, and i was contemplating of reverting it too.

should we revert it too or do you think there is a better way of handling it @ruihe774?

I think we need to revert it. cc @handlerug

@low-batt
Copy link
Contributor

I just confirmed that #13348 still reproduces with libmpv built from the current master. This PR did not fix it.

@ruihe774
Copy link
Contributor

ruihe774 commented Apr 19, 2024

I just confirmed that #13348 still reproduces with libmpv built from the current master. This PR did not fix it.

Yes. We need another revert for 0341a6f. I'm still waiting for response from @handlerug.

@handlerug
Copy link
Contributor

handlerug commented Apr 19, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Audio stuttering on macOS since v0.37.0
8 participants