Skip to content

Commit

Permalink
ao_avfoundation: tidy
Browse files Browse the repository at this point in the history
  • Loading branch information
ruihe774 committed Mar 25, 2024
1 parent f57da51 commit 477310e
Showing 1 changed file with 39 additions and 32 deletions.
71 changes: 39 additions & 32 deletions audio/out/ao_avfoundation.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,16 @@ static CMTime CMTimeFromNanoseconds(int64_t time)
static void feed(struct ao *ao)
{
struct priv *p = ao->priv;
int samplerate = ao->samplerate;
int sstride = ao->sstride;

CMBlockBufferRef block_buffer = NULL;
CMSampleBufferRef sample_buffer = NULL;
OSStatus err;

int64_t cur_time_av = CMTimeGetNanoseconds([p->synchronizer currentTime]);
int64_t cur_time_mp = mp_time_ns();
p->end_time_av = MPMAX(p->end_time_av, cur_time_av);

int request_sample_count = ao->samplerate / 10; // 1/10 samplerate may be a good number
int buffer_size = request_sample_count * ao->sstride;
if (CMBlockBufferCreateWithMemoryBlock(
int request_sample_count = samplerate / 10;
int buffer_size = request_sample_count * sstride;
if ((err = CMBlockBufferCreateWithMemoryBlock(
kCFAllocatorDefault,
NULL,
buffer_size,
Expand All @@ -80,30 +80,36 @@ static void feed(struct ao *ao)
buffer_size,
kCMBlockBufferAssureMemoryNowFlag,
&block_buffer
) != noErr) {
MP_FATAL(ao, "failed to create CMBlockBuffer\n");
)) != noErr) {
MP_FATAL(ao, "failed to create block buffer\n");
MP_VERBOSE(ao, "CMBlockBufferCreateWithMemoryBlock returned %d\n", err);
goto error;
}
void* data[1];
if (CMBlockBufferGetDataPointer(block_buffer, 0, NULL, NULL, (char**)data) != noErr) {
MP_FATAL(ao, "CMBlockBufferGetDataPointer failed\n");
if ((err = CMBlockBufferGetDataPointer(block_buffer, 0, NULL, NULL, (char**)data)) != noErr) {
MP_FATAL(ao, "failed to get data pointer from block buffer\n");
MP_VERBOSE(ao, "CMBlockBufferGetDataPointer returned %d\n", err);
goto error;
}

int64_t delta = CMTimeGetNanoseconds(CMTimeMake(request_sample_count, ao->samplerate));
int real_sample_count = ao_read_data_nonblocking(ao, data, request_sample_count, p->end_time_av - cur_time_av + cur_time_mp + delta);
int64_t cur_time_av = CMTimeGetNanoseconds([p->synchronizer currentTime]);
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) {
mp_sleep_ns(1000000); // avoid spinning
// avoid spinning by blocking the thread.
mp_sleep_ns(1000000);
goto finish;
}

CMSampleTimingInfo sample_timing_into[] = {(CMSampleTimingInfo) {
.duration = CMTimeMake(1, ao->samplerate),
.presentationTimeStamp = CMTimeFromNanoseconds(p->end_time_av),
.duration = CMTimeMake(1, samplerate),
.presentationTimeStamp = CMTimeFromNanoseconds(end_time_av),
.decodeTimeStamp = kCMTimeInvalid
}};
size_t sample_size_array[] = {ao->sstride};
if (CMSampleBufferCreateReady(
size_t sample_size_array[] = {sstride};
if ((err = CMSampleBufferCreateReady(
kCFAllocatorDefault,
block_buffer,
p->format_description,
Expand All @@ -113,15 +119,16 @@ static void feed(struct ao *ao)
1,
sample_size_array,
&sample_buffer
) != noErr) {
MP_FATAL(ao, "failed to create CMSampleBuffe\n");
)) != noErr) {
MP_FATAL(ao, "failed to create sample buffer\n");
MP_VERBOSE(ao, "CMSampleBufferCreateReady returned %d\n", err);
goto error;
}

[p->renderer enqueueSampleBuffer:sample_buffer];

delta = CMTimeGetNanoseconds(CMTimeMake(real_sample_count, ao->samplerate));
p->end_time_av += delta;
time_delta = CMTimeGetNanoseconds(CMTimeMake(real_sample_count, samplerate));
p->end_time_av = end_time_av + time_delta;

goto finish;

Expand Down Expand Up @@ -162,21 +169,16 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
case AOCONTROL_GET_MUTE:
*(bool*)arg = [p->renderer isMuted];
return CONTROL_OK;

case AOCONTROL_GET_VOLUME:
*(float*)arg = [p->renderer volume] * 100;
return CONTROL_OK;

case AOCONTROL_SET_MUTE:
[p->renderer setMuted:*(bool*)arg];
return CONTROL_OK;

case AOCONTROL_SET_VOLUME:
[p->renderer setVolume:*(float*)arg / 100];
return CONTROL_OK;

default:
// AOCONTROL_UPDATE_STREAM_TITLE should be handled by remote_command_center.swift
return CONTROL_UNKNOWN;
}
}
Expand Down Expand Up @@ -211,18 +213,21 @@ static int init(struct ao *ao)
#endif

if ((p->renderer = [[AVSampleBufferAudioRenderer alloc] init]) == nil) {
MP_FATAL(ao, "failed to create AVSampleBufferAudioRenderer\n");
MP_FATAL(ao, "failed to create audio renderer\n");
MP_VERBOSE(ao, "AVSampleBufferAudioRenderer failed to initialize\n");
goto error;
}
if ((p->synchronizer = [[AVSampleBufferRenderSynchronizer alloc] init]) == nil) {
MP_FATAL(ao, "failed to create AVSampleBufferRenderSynchronizer\n");
MP_FATAL(ao, "failed to create rendering synchronizer\n");
MP_VERBOSE(ao, "AVSampleBufferRenderSynchronizer failed to initialize\n");
goto error;
}
if ((p->queue = dispatch_queue_create(
"avfoundation event",
dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, 0)
)) == NULL) {
MP_FATAL(ao, "failed to create dispatch queue\n");
MP_VERBOSE(ao, "dispatch_queue_create failed\n");
goto error;
}

Expand Down Expand Up @@ -269,7 +274,8 @@ static int init(struct ao *ao)
talloc_free(talloc_ctx);
ca_log_layout(ao, MSGL_V, layout);

if (CMAudioFormatDescriptionCreate(
OSStatus err;
if ((err = CMAudioFormatDescriptionCreate(
kCFAllocatorDefault,
&asbd,
layout_size,
Expand All @@ -278,8 +284,9 @@ static int init(struct ao *ao)
NULL,
NULL,
&p->format_description
) != noErr) {
MP_FATAL(ao, "failed to create CMAudioFormatDescription\n");
)) != noErr) {
MP_FATAL(ao, "failed to create audio format description\n");
MP_VERBOSE(ao, "CMAudioFormatDescriptionCreate returned %d\n", err);
goto error;
}
talloc_free(layout);
Expand Down

0 comments on commit 477310e

Please sign in to comment.