diff options
Diffstat (limited to 'audio')
-rw-r--r-- | audio/filter/af_scaletempo.c | 4 | ||||
-rw-r--r-- | audio/out/ao.c | 19 | ||||
-rw-r--r-- | audio/out/ao.h | 4 | ||||
-rw-r--r-- | audio/out/ao_coreaudio.c | 65 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_properties.c | 6 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_properties.h | 2 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_utils.c | 110 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_utils.h | 31 | ||||
-rw-r--r-- | audio/out/ao_wasapi.c | 12 |
9 files changed, 133 insertions, 120 deletions
diff --git a/audio/filter/af_scaletempo.c b/audio/filter/af_scaletempo.c index b12954f1af..d409ed85cf 100644 --- a/audio/filter/af_scaletempo.c +++ b/audio/filter/af_scaletempo.c @@ -444,11 +444,11 @@ static int control(struct af_instance* af, int cmd, void* arg) if (s->speed_pitch) { break; } - s->speed = *(float*)arg; + s->speed = *(double *)arg; s->scale = s->speed * s->scale_nominal; } else { if (s->speed_pitch) { - s->speed = 1 / *(float*)arg; + s->speed = 1 / *(double *)arg; s->scale = s->speed * s->scale_nominal; break; } diff --git a/audio/out/ao.c b/audio/out/ao.c index 04e6fcda12..49fffb657d 100644 --- a/audio/out/ao.c +++ b/audio/out/ao.c @@ -30,6 +30,7 @@ #include "core/options.h" #include "core/m_config.h" #include "core/mp_msg.h" +#include "core/mpv_global.h" // there are some globals: struct ao *global_ao; @@ -121,27 +122,31 @@ const struct m_obj_list ao_obj_list = { .allow_trailer = true, }; -static struct ao *ao_create(bool probing, struct MPOpts *opts, +static struct ao *ao_create(bool probing, struct mpv_global *global, struct input_ctx *input_ctx, struct encode_lavc_context *encode_lavc_ctx, int samplerate, int format, struct mp_chmap channels, char *name, char **args) { + struct mp_log *log = mp_log_new(NULL, global->log, "ao"); struct m_obj_desc desc; if (!m_obj_list_find(&desc, &ao_obj_list, bstr0(name))) { - mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "Audio output %s not found!\n", name); + mp_tmsg_log(log, MSGL_ERR, "Audio output %s not found!\n", name); + talloc_free(log); return NULL; }; struct ao *ao = talloc_ptrtype(NULL, ao); + talloc_steal(ao, log); *ao = (struct ao) { .driver = desc.p, .probing = probing, - .opts = opts, + .opts = global->opts, .encode_lavc_ctx = encode_lavc_ctx, .input_ctx = input_ctx, .samplerate = samplerate, .channels = channels, .format = format, + .log = mp_log_new(ao, log, name), }; if (ao->driver->encode != !!ao->encode_lavc_ctx) goto error; @@ -158,19 +163,19 @@ error: return NULL; } -struct ao *ao_init_best(struct MPOpts *opts, +struct ao *ao_init_best(struct mpv_global *global, struct input_ctx *input_ctx, struct encode_lavc_context *encode_lavc_ctx, int samplerate, int format, struct mp_chmap channels) { - struct m_obj_settings *ao_list = opts->audio_driver_list; + struct m_obj_settings *ao_list = global->opts->audio_driver_list; if (ao_list && ao_list[0].name) { for (int n = 0; ao_list[n].name; n++) { if (strlen(ao_list[n].name) == 0) goto autoprobe; mp_tmsg(MSGT_AO, MSGL_V, "Trying preferred audio driver '%s'\n", ao_list[n].name); - struct ao *ao = ao_create(false, opts, input_ctx, encode_lavc_ctx, + struct ao *ao = ao_create(false, global, input_ctx, encode_lavc_ctx, samplerate, format, channels, ao_list[n].name, ao_list[n].attribs); if (ao) @@ -183,7 +188,7 @@ struct ao *ao_init_best(struct MPOpts *opts, autoprobe: // now try the rest... for (int i = 0; audio_out_drivers[i]; i++) { - struct ao *ao = ao_create(true, opts, input_ctx, encode_lavc_ctx, + struct ao *ao = ao_create(true, global, input_ctx, encode_lavc_ctx, samplerate, format, channels, (char *)audio_out_drivers[i]->info->short_name, NULL); if (ao) diff --git a/audio/out/ao.h b/audio/out/ao.h index 25cd12a0f1..65e5a3fc6b 100644 --- a/audio/out/ao.h +++ b/audio/out/ao.h @@ -93,11 +93,13 @@ struct ao { struct encode_lavc_context *encode_lavc_ctx; struct MPOpts *opts; struct input_ctx *input_ctx; + struct mp_log *log; // Using e.g. "[ao/coreaudio]" as prefix }; extern char *ao_subdevice; -struct ao *ao_init_best(struct MPOpts *opts, +struct mpv_global; +struct ao *ao_init_best(struct mpv_global *global, struct input_ctx *input_ctx, struct encode_lavc_context *encode_lavc_ctx, int samplerate, int format, struct mp_chmap channels); diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c index 718c71187d..59e1f82f36 100644 --- a/audio/out/ao_coreaudio.c +++ b/audio/out/ao_coreaudio.c @@ -46,10 +46,10 @@ static void audio_pause(struct ao *ao); static void audio_resume(struct ao *ao); static void reset(struct ao *ao); -static void print_buffer(struct mp_ring *buffer) +static void print_buffer(struct ao *ao, struct mp_ring *buffer) { void *tctx = talloc_new(NULL); - ca_msg(MSGL_V, "%s\n", mp_ring_repr(buffer, tctx)); + MP_VERBOSE(ao, "%s\n", mp_ring_repr(buffer, tctx)); talloc_free(tctx); } @@ -109,7 +109,12 @@ static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags, AudioBuffer buf = buffer_list->mBuffers[0]; int requested = buf.mDataByteSize; - buf.mDataByteSize = mp_ring_read(p->buffer, buf.mData, requested); + if (mp_ring_buffered(p->buffer) < requested) { + MP_VERBOSE(ao, "buffer underrun\n"); + audio_pause(ao); + } else { + mp_ring_read(p->buffer, buf.mData, requested); + } return noErr; } @@ -192,7 +197,7 @@ coreaudio_error: return CONTROL_ERROR; } -static void print_list(void) +static void print_list(struct ao *ao) { char *help = talloc_strdup(NULL, "Available output devices:\n"); @@ -221,7 +226,7 @@ static void print_list(void) talloc_free(devs); coreaudio_error: - ca_msg(MSGL_INFO, "%s", help); + MP_INFO(ao, "%s", help); talloc_free(help); } @@ -233,7 +238,7 @@ static int init(struct ao *ao) OSStatus err; struct priv *p = ao->priv; - if (p->opt_list) print_list(); + if (p->opt_list) print_list(ao); struct priv_d *d = talloc_zero(p, struct priv_d); @@ -266,9 +271,8 @@ static int init(struct ao *ao) err = CA_GET_STR(selected_device, kAudioObjectPropertyName, &device_name); CHECK_CA_ERROR("could not get selected audio device name"); - ca_msg(MSGL_V, - "selected audio output device: %s (%" PRIu32 ")\n", - device_name, selected_device); + MP_VERBOSE(ao, "selected audio output device: %s (%" PRIu32 ")\n", + device_name, selected_device); talloc_free(device_name); @@ -278,7 +282,7 @@ static int init(struct ao *ao) bool supports_digital = false; /* Probe whether device support S/PDIF stream output if input is AC3 stream. */ if (AF_FORMAT_IS_AC3(ao->format)) { - if (ca_device_supports_digital(selected_device)) + if (ca_device_supports_digital(ao, selected_device)) supports_digital = true; } @@ -293,7 +297,7 @@ static int init(struct ao *ao) uint32_t *bitmaps; size_t n_bitmaps; - ca_bitmaps_from_layouts(layouts, n_layouts, &bitmaps, &n_bitmaps); + ca_bitmaps_from_layouts(ao, layouts, n_layouts, &bitmaps, &n_bitmaps); talloc_free(layouts); struct mp_chmap_sel chmap_sel = {0}; @@ -339,7 +343,7 @@ static int init(struct ao *ao) asbd.mFramesPerPacket * asbd.mChannelsPerFrame * (asbd.mBitsPerChannel / 8); - ca_print_asbd("source format:", &asbd); + ca_print_asbd(ao, "source format:", &asbd); if (supports_digital) return init_digital(ao, asbd); @@ -358,7 +362,9 @@ static int init_lpcm(struct ao *ao, AudioStreamBasicDescription asbd) AudioComponentDescription desc = (AudioComponentDescription) { .componentType = kAudioUnitType_Output, - .componentSubType = kAudioUnitSubType_HALOutput, + .componentSubType = (p->opt_device_id < 0) ? + kAudioUnitSubType_DefaultOutput : + kAudioUnitSubType_HALOutput, .componentManufacturer = kAudioUnitManufacturer_Apple, .componentFlags = 0, .componentFlagsMask = 0, @@ -366,7 +372,7 @@ static int init_lpcm(struct ao *ao, AudioStreamBasicDescription asbd) AudioComponent comp = AudioComponentFindNext(NULL, &desc); if (comp == NULL) { - ca_msg(MSGL_ERR, "unable to find audio component\n"); + MP_ERR(ao, "unable to find audio component\n"); goto coreaudio_error; } @@ -410,7 +416,7 @@ static int init_lpcm(struct ao *ao, AudioStreamBasicDescription asbd) } p->buffer = mp_ring_new(p, get_ring_size(ao)); - print_buffer(p->buffer); + print_buffer(ao, p->buffer); AURenderCallbackStruct render_cb = (AURenderCallbackStruct) { .inputProc = render_cb_lpcm, @@ -447,14 +453,14 @@ static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd) CHECK_CA_WARN("could not check whether device is alive"); if (!is_alive) - ca_msg(MSGL_WARN, "device is not alive\n"); + MP_WARN(ao , "device is not alive\n"); p->is_digital = 1; err = ca_lock_device(p->device, &d->hog_pid); CHECK_CA_WARN("failed to set hogmode"); - err = ca_disable_mixing(p->device, &d->changed_mixing); + err = ca_disable_mixing(ao, p->device, &d->changed_mixing); CHECK_CA_WARN("failed to disable mixing"); AudioStreamID *streams; @@ -467,7 +473,7 @@ static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd) CHECK_CA_ERROR("could not get number of streams"); for (int i = 0; i < n_streams && d->stream_idx < 0; i++) { - bool digital = ca_stream_supports_digital(streams[i]); + bool digital = ca_stream_supports_digital(ao, streams[i]); if (digital) { err = CA_GET(streams[i], kAudioStreamPropertyPhysicalFormat, @@ -518,11 +524,11 @@ static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd) talloc_free(streams); if (d->stream_idx < 0) { - ca_msg(MSGL_WARN, "can't find any digital output stream format\n"); + MP_WARN(ao , "can't find any digital output stream format\n"); goto coreaudio_error; } - if (!ca_change_format(d->stream, d->stream_asbd)) + if (!ca_change_format(ao, d->stream, d->stream_asbd)) goto coreaudio_error; void *changed = (void *) &(d->stream_asbd_changed); @@ -537,8 +543,7 @@ static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd) ao->format = AF_FORMAT_AC3_LE; else if (d->stream_asbd.mFormatFlags & kAudioFormatFlagIsBigEndian) #endif - ca_msg(MSGL_WARN, - "stream has non-native byte order, digital output may fail\n"); + MP_WARN(ao, "stream has non-native byte order, output may fail\n"); ao->samplerate = d->stream_asbd.mSampleRate; ao->bps = ao->samplerate * @@ -546,7 +551,7 @@ static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd) d->stream_asbd.mFramesPerPacket); p->buffer = mp_ring_new(p, get_ring_size(ao)); - print_buffer(p->buffer); + print_buffer(ao, p->buffer); err = AudioDeviceCreateIOProcID(p->device, (AudioDeviceIOProc)render_cb_digital, @@ -573,11 +578,11 @@ static int play(struct ao *ao, void *output_samples, int num_bytes, int flags) // Check whether we need to reset the digital output stream. if (p->is_digital && d->stream_asbd_changed) { d->stream_asbd_changed = 0; - if (ca_stream_supports_digital(d->stream)) { - if (!ca_change_format(d->stream, d->stream_asbd)) { - ca_msg(MSGL_WARN, "can't restore digital output\n"); + if (ca_stream_supports_digital(ao, d->stream)) { + if (!ca_change_format(ao, d->stream, d->stream_asbd)) { + MP_WARN(ao , "can't restore digital output\n"); } else { - ca_msg(MSGL_WARN, "restoring digital output succeeded.\n"); + MP_WARN(ao, "restoring digital output succeeded.\n"); reset(ao); } } @@ -635,10 +640,10 @@ static void uninit(struct ao *ao, bool immed) err = AudioDeviceDestroyIOProcID(p->device, d->render_cb); CHECK_CA_WARN("failed to remove device render callback"); - if (!ca_change_format(d->stream, d->original_asbd)) - ca_msg(MSGL_WARN, "can't revert to original device format"); + if (!ca_change_format(ao, d->stream, d->original_asbd)) + MP_WARN(ao, "can't revert to original device format"); - err = ca_enable_mixing(p->device, d->changed_mixing); + err = ca_enable_mixing(ao, p->device, d->changed_mixing); CHECK_CA_WARN("can't re-enable mixing"); err = ca_unlock_device(p->device, &d->hog_pid); diff --git a/audio/out/ao_coreaudio_properties.c b/audio/out/ao_coreaudio_properties.c index 300f27a8f0..67287e7427 100644 --- a/audio/out/ao_coreaudio_properties.c +++ b/audio/out/ao_coreaudio_properties.c @@ -60,13 +60,13 @@ OSStatus ca_get_ary(AudioObjectID id, ca_scope scope, ca_sel selector, }; err = AudioObjectGetPropertyDataSize(id, &p_addr, 0, NULL, &p_size); - CHECK_CA_ERROR("can't fetch property size"); + CHECK_CA_ERROR_SILENT_L(coreaudio_error); *data = talloc_size(NULL, p_size); *elements = p_size / element_size; err = ca_get(id, scope, selector, p_size, *data); - CHECK_CA_ERROR_L(coreaudio_error_free, "can't fetch property data"); + CHECK_CA_ERROR_SILENT_L(coreaudio_error_free); return err; coreaudio_error_free: @@ -81,7 +81,7 @@ OSStatus ca_get_str(AudioObjectID id, ca_scope scope, ca_sel selector, CFStringRef string; OSStatus err = ca_get(id, scope, selector, sizeof(CFStringRef), (void **)&string); - CHECK_CA_ERROR("Can't fetch string property"); + CHECK_CA_ERROR_SILENT_L(coreaudio_error); CFIndex size = CFStringGetMaximumSizeForEncoding( diff --git a/audio/out/ao_coreaudio_properties.h b/audio/out/ao_coreaudio_properties.h index 88ba889c29..ee7f83e6b7 100644 --- a/audio/out/ao_coreaudio_properties.h +++ b/audio/out/ao_coreaudio_properties.h @@ -25,7 +25,7 @@ #define ca_sel AudioObjectPropertySelector #define ca_scope AudioObjectPropertyScope #define CA_GLOBAL kAudioObjectPropertyScopeGlobal -#define CA_OUTPUT kAudioObjectPropertyScopeOutput +#define CA_OUTPUT kAudioDevicePropertyScopeOutput OSStatus ca_get(AudioObjectID id, ca_scope scope, ca_sel selector, uint32_t size, void *data); diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c index 68c87f9cc6..2c12b562cf 100644 --- a/audio/out/ao_coreaudio_utils.c +++ b/audio/out/ao_coreaudio_utils.c @@ -26,9 +26,6 @@ #include "audio/out/ao_coreaudio_properties.h" #include "osdep/timer.h" -#define ca_msg(a, b ...) mp_msg(MSGT_AO, a, "AO: [coreaudio] " b) -#define CA_CFSTR_ENCODING kCFStringEncodingASCII - char *fourcc_repr(void *talloc_ctx, uint32_t code) { // Extract FourCC letters from the uint32_t and finde out if it's a valid @@ -55,24 +52,24 @@ char *fourcc_repr(void *talloc_ctx, uint32_t code) return repr; } -bool check_ca_st(int level, OSStatus code, const char *message) +bool check_ca_st(struct ao *ao, int level, OSStatus code, const char *message) { if (code == noErr) return true; char *error_string = fourcc_repr(NULL, code); - ca_msg(level, "%s (%s)\n", message, error_string); + mp_msg_log(ao->log, level, "%s (%s)\n", message, error_string); talloc_free(error_string); return false; } -void ca_print_asbd(const char *description, +void ca_print_asbd(struct ao *ao, const char *description, const AudioStreamBasicDescription *asbd) { uint32_t flags = asbd->mFormatFlags; char *format = fourcc_repr(NULL, asbd->mFormatID); - ca_msg(MSGL_V, + MP_VERBOSE(ao, "%s %7.1fHz %" PRIu32 "bit [%s]" "[%" PRIu32 "][%" PRIu32 "][%" PRIu32 "]" "[%" PRIu32 "][%" PRIu32 "] " @@ -101,7 +98,7 @@ bool ca_format_is_digital(AudioStreamBasicDescription asbd) return false; } -bool ca_stream_supports_digital(AudioStreamID stream) +bool ca_stream_supports_digital(struct ao *ao, AudioStreamID stream) { AudioStreamRangedDescription *formats = NULL; size_t n_formats; @@ -114,7 +111,7 @@ bool ca_stream_supports_digital(AudioStreamID stream) for (int i = 0; i < n_formats; i++) { AudioStreamBasicDescription asbd = formats[i].mFormat; - ca_print_asbd("supported format:", &(asbd)); + ca_print_asbd(ao, "supported format:", &(asbd)); if (ca_format_is_digital(asbd)) { talloc_free(formats); return true; @@ -126,7 +123,7 @@ coreaudio_error: return false; } -bool ca_device_supports_digital(AudioDeviceID device) +bool ca_device_supports_digital(struct ao *ao, AudioDeviceID device) { AudioStreamID *streams = NULL; size_t n_streams; @@ -138,7 +135,7 @@ bool ca_device_supports_digital(AudioDeviceID device) CHECK_CA_ERROR("could not get number of streams."); for (int i = 0; i < n_streams; i++) { - if (ca_stream_supports_digital(streams[i])) { + if (ca_stream_supports_digital(ao, streams[i])) { talloc_free(streams); return true; } @@ -159,8 +156,6 @@ OSStatus ca_property_listener(AudioObjectPropertySelector selector, for (int i = 0; i < n_addresses; i++) { if (addresses[i].mSelector == selector) { - ca_msg(MSGL_WARN, "event: property %s changed\n", - fourcc_repr(talloc_ctx, selector)); if (data) *(volatile int *)data = 1; break; } @@ -202,8 +197,8 @@ OSStatus ca_unlock_device(AudioDeviceID device, pid_t *pid) { return noErr; } -static OSStatus ca_change_mixing(AudioDeviceID device, uint32_t val, - bool *changed) { +static OSStatus ca_change_mixing(struct ao *ao, AudioDeviceID device, + uint32_t val, bool *changed) { *changed = false; AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) { @@ -239,14 +234,14 @@ static OSStatus ca_change_mixing(AudioDeviceID device, uint32_t val, return noErr; } -OSStatus ca_disable_mixing(AudioDeviceID device, bool *changed) { - return ca_change_mixing(device, 0, changed); +OSStatus ca_disable_mixing(struct ao *ao, AudioDeviceID device, bool *changed) { + return ca_change_mixing(ao, device, 0, changed); } -OSStatus ca_enable_mixing(AudioDeviceID device, bool changed) { +OSStatus ca_enable_mixing(struct ao *ao, AudioDeviceID device, bool changed) { if (changed) { bool dont_care = false; - return ca_change_mixing(device, 1, &dont_care); + return ca_change_mixing(ao, device, 1, &dont_care); } return noErr; @@ -278,14 +273,14 @@ OSStatus ca_disable_device_listener(AudioDeviceID device, void *flag) { return ca_change_device_listening(device, flag, false); } -bool ca_change_format(AudioStreamID stream, +bool ca_change_format(struct ao *ao, AudioStreamID stream, AudioStreamBasicDescription change_format) { OSStatus err = noErr; AudioObjectPropertyAddress p_addr; volatile int stream_format_changed = 0; - ca_print_asbd("setting stream format:", &change_format); + ca_print_asbd(ao, "setting stream format:", &change_format); /* Install the callback. */ p_addr = (AudioObjectPropertyAddress) { @@ -317,13 +312,13 @@ bool ca_change_format(AudioStreamID stream, if (stream_format_changed) { stream_format_changed = 0; } else { - ca_msg(MSGL_V, "reached timeout\n"); + MP_VERBOSE(ao, "reached timeout\n"); } AudioStreamBasicDescription actual_format; err = CA_GET(stream, kAudioStreamPropertyPhysicalFormat, &actual_format); - ca_print_asbd("actual format in use:", &actual_format); + ca_print_asbd(ao, "actual format in use:", &actual_format); if (actual_format.mSampleRate == change_format.mSampleRate && actual_format.mFormatID == change_format.mFormatID && actual_format.mFramesPerPacket == change_format.mFramesPerPacket) { @@ -341,33 +336,8 @@ bool ca_change_format(AudioStreamID stream, return format_set; } -void ca_bitmaps_from_layouts(AudioChannelLayout *layouts, size_t n_layouts, - uint32_t **bitmaps, size_t *n_bitmaps) -{ - *n_bitmaps = 0; - *bitmaps = talloc_array_size(NULL, sizeof(uint32_t), n_layouts); - - for (int i=0; i < n_layouts; i++) { - uint32_t bitmap = 0; - - switch (layouts[i].mChannelLayoutTag) { - case kAudioChannelLayoutTag_UseChannelBitmap: - (*bitmaps)[(*n_bitmaps)++] = layouts[i].mChannelBitmap; - break; - - case kAudioChannelLayoutTag_UseChannelDescriptions: - if (ca_bitmap_from_ch_desc(&layouts[i], &bitmap)) - (*bitmaps)[(*n_bitmaps)++] = bitmap; - break; - - default: - if (ca_bitmap_from_ch_tag(&layouts[i], &bitmap)) - (*bitmaps)[(*n_bitmaps)++] = bitmap; - } - } -} - -bool ca_bitmap_from_ch_desc(AudioChannelLayout *layout, uint32_t *bitmap) +static bool ca_bitmap_from_ch_desc(struct ao *ao, AudioChannelLayout *layout, + uint32_t *bitmap) { // If the channel layout uses channel descriptions, from my // exepriments there are there three possibile cases: @@ -388,9 +358,8 @@ bool ca_bitmap_from_ch_desc(AudioChannelLayout *layout, uint32_t *bitmap) if (label == kAudioChannelLabel_UseCoordinates || label == kAudioChannelLabel_Unknown || label > kAudioChannelLabel_TopBackRight) { - ca_msg(MSGL_V, - "channel label=%d unusable to build channel " - "bitmap, skipping layout\n", label); + MP_VERBOSE(ao, "channel label=%d unusable to build channel " + "bitmap, skipping layout\n", label); all_channels_valid = false; } else { *bitmap |= 1ULL << (label - 1); @@ -400,7 +369,8 @@ bool ca_bitmap_from_ch_desc(AudioChannelLayout *layout, uint32_t *bitmap) return all_channels_valid; } -bool ca_bitmap_from_ch_tag(AudioChannelLayout *layout, uint32_t *bitmap) +static bool ca_bitmap_from_ch_tag(struct ao *ao, AudioChannelLayout *layout, + uint32_t *bitmap) { // This layout is defined exclusively by it's tag. Use the Audio // Format Services API to try and convert it to a bitmap that @@ -413,11 +383,37 @@ bool ca_bitmap_from_ch_tag(AudioChannelLayout *layout, uint32_t *bitmap) sizeof(AudioChannelLayoutTag), &tag, &bitmap_size, bitmap); if (err != noErr) { - ca_msg(MSGL_V, - "channel layout tag=%d unusable to build channel " - "bitmap, skipping layout\n", tag); + MP_VERBOSE(ao, "channel layout tag=%d unusable to build channel " + "bitmap, skipping layout\n", tag); return false; } else { return true; } } + +void ca_bitmaps_from_layouts(struct ao *ao, + AudioChannelLayout *layouts, size_t n_layouts, + uint32_t **bitmaps, size_t *n_bitmaps) +{ + *n_bitmaps = 0; + *bitmaps = talloc_array_size(NULL, sizeof(uint32_t), n_layouts); + + for (int i=0; i < n_layouts; i++) { + uint32_t bitmap = 0; + + switch (layouts[i].mChannelLayoutTag) { + case kAudioChannelLayoutTag_UseChannelBitmap: + (*bitmaps)[(*n_bitmaps)++] = layouts[i].mChannelBitmap; + break; + + case kAudioChannelLayoutTag_UseChannelDescriptions: + if (ca_bitmap_from_ch_desc(ao, &layouts[i], &bitmap)) + (*bitmaps)[(*n_bitmaps)++] = bitmap; + break; + + default: + if (ca_bitmap_from_ch_tag(ao, &layouts[i], &bitmap)) + (*bitmaps)[(*n_bitmaps)++] = bitmap; + } + } +} diff --git a/audio/out/ao_coreaudio_utils.h b/audio/out/ao_coreaudio_utils.h index 78e524fbd8..96383f9870 100644 --- a/audio/out/ao_coreaudio_utils.h +++ b/audio/out/ao_coreaudio_utils.h @@ -23,29 +23,34 @@ #include <inttypes.h> #include <stdbool.h> #include "core/mp_msg.h" +#include "audio/out/ao.h" -#define ca_msg(a, b ...) mp_msg(MSGT_AO, a, "AO: [coreaudio] " b) #define CA_CFSTR_ENCODING kCFStringEncodingASCII char *fourcc_repr(void *talloc_ctx, uint32_t code); -bool check_ca_st(int level, OSStatus code, const char *message); +bool check_ca_st(struct ao *ao, int level, OSStatus code, const char *message); #define CHECK_CA_ERROR_L(label, message) \ do { \ - if (!check_ca_st(MSGL_ERR, err, message)) { \ + if (!check_ca_st(ao, MSGL_ERR, err, message)) { \ goto label; \ } \ } while (0) #define CHECK_CA_ERROR(message) CHECK_CA_ERROR_L(coreaudio_error, message) -#define CHECK_CA_WARN(message) check_ca_st(MSGL_WARN, err, message) +#define CHECK_CA_WARN(message) check_ca_st(ao, MSGL_WARN, err, message) -void ca_print_asbd(const char *description, +#define CHECK_CA_ERROR_SILENT_L(label) \ + do { \ + if (err != noErr) goto label; \ + } while (0) + +void ca_print_asbd(struct ao *ao, const char *description, const AudioStreamBasicDescription *asbd); bool ca_format_is_digital(AudioStreamBasicDescription asbd); -bool ca_stream_supports_digital(AudioStreamID stream); -bool ca_device_supports_digital(AudioDeviceID device); +bool ca_stream_supports_digital(struct ao *ao, AudioStreamID stream); +bool ca_device_supports_digital(struct ao *ao, AudioDeviceID device); OSStatus ca_property_listener(AudioObjectPropertySelector selector, AudioObjectID object, uint32_t n_addresses, @@ -62,17 +67,17 @@ OSStatus ca_device_listener(AudioObjectID object, uint32_t n_addresses, OSStatus ca_lock_device(AudioDeviceID device, pid_t *pid); OSStatus ca_unlock_device(AudioDeviceID device, pid_t *pid); -OSStatus ca_disable_mixing(AudioDeviceID device, bool *changed); -OSStatus ca_enable_mixing(AudioDeviceID device, bool changed); +OSStatus ca_disable_mixing(struct ao *ao, AudioDeviceID device, bool *changed); +OSStatus ca_enable_mixing(struct ao *ao, AudioDeviceID device, bool changed); + OSStatus ca_enable_device_listener(AudioDeviceID device, void *flag); OSStatus ca_disable_device_listener(AudioDeviceID device, void *flag); -bool ca_change_format(AudioStreamID stream, +bool ca_change_format(struct ao *ao, AudioStreamID stream, AudioStreamBasicDescription change_format); -bool ca_bitmap_from_ch_desc(AudioChannelLayout *layout, uint32_t *bitmap); -bool ca_bitmap_from_ch_tag(AudioChannelLayout *layout, uint32_t *bitmap); -void ca_bitmaps_from_layouts(AudioChannelLayout *layouts, size_t n_layouts, +void ca_bitmaps_from_layouts(struct ao *ao, + AudioChannelLayout *layouts, size_t n_layouts, uint32_t **bitmaps, size_t *n_bitmaps); #endif /* MPV_COREAUDIO_UTILS_H */ diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c index 0e8d40f2bf..03a733ce33 100644 --- a/audio/out/ao_wasapi.c +++ b/audio/out/ao_wasapi.c @@ -294,8 +294,8 @@ static int set_ao_format(struct wasapi_state *state, wformat.Format.wBitsPerSample, wformat.SubFormat.Data1 == 3); if (wformat.SubFormat.Data1 != 1 && wformat.SubFormat.Data1 != 3) { - mp_msg(MSGT_AO, MSGL_ERR, "ao-wasapi: unknown SubFormat %d\n", - wformat.SubFormat.Data1); + mp_msg(MSGT_AO, MSGL_ERR, "ao-wasapi: unknown SubFormat %"PRIu32"\n", + (uint32_t)wformat.SubFormat.Data1); return 0; } @@ -798,8 +798,8 @@ static int enumerate_devices(void) { CoUninitialize(); return 0; exit_label: - mp_msg(MSGT_AO, MSGL_ERR, "Error enumerating devices: HRESULT %08x \"%s\"\n", - hr, explain_err(hr)); + mp_msg(MSGT_AO, MSGL_ERR, "Error enumerating devices: HRESULT %08"PRIx32" \"%s\"\n", + (uint32_t)hr, explain_err(hr)); CoUninitialize(); return 1; } @@ -1044,7 +1044,7 @@ static void thread_feed(wasapi_state *state,int force_feed) return; exit_label: EnterCriticalSection(&state->print_lock); - mp_msg(MSGT_AO, MSGL_ERR, "ao-wasapi: thread_feed fails with %"PRIx32"!\n", hr); + mp_msg(MSGT_AO, MSGL_ERR, "ao-wasapi: thread_feed fails with %"PRIx32"!\n", (uint32_t)hr); LeaveCriticalSection(&state->print_lock); return; } @@ -1107,7 +1107,7 @@ static void thread_uninit(wasapi_state *state) ExitThread(0); } -static unsigned int __stdcall ThreadLoop(void *lpParameter) +static DWORD __stdcall ThreadLoop(void *lpParameter) { struct ao *ao = lpParameter; int feedwatch = 0; |