vlc | branch: master | Thomas Guillem <[email protected]> | Fri Mar 3 10:50:29 2017 +0100| [8f1ae66aee9c6b45a0e75ec579d3d4bb333cc289] | committer: Thomas Guillem
audiounit_ios: add AC3/DTS passthrough support As there is no way to know if an audio device support a codec via passthrough. The encoded output should be enabled by the user via the following libvlc call: libvlc_audio_output_device_set(mp, NULL, "ENCODED"); Even if the ENCODED output is selected, passthrough will be selected only if the current port is USB or HDMI. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8f1ae66aee9c6b45a0e75ec579d3d4bb333cc289 --- modules/audio_output/audiounit_ios.m | 75 ++++++++++++++++++++++++++++++--- modules/audio_output/coreaudio_common.c | 39 +++++++++++------ 2 files changed, 97 insertions(+), 17 deletions(-) diff --git a/modules/audio_output/audiounit_ios.m b/modules/audio_output/audiounit_ios.m index d636c4d..5884e1a 100644 --- a/modules/audio_output/audiounit_ios.m +++ b/modules/audio_output/audiounit_ios.m @@ -56,6 +56,22 @@ vlc_module_end () @property (readonly, assign) audio_output_t* aout; @end +enum au_dev +{ + AU_DEV_PCM, + AU_DEV_ENCODED, +}; + +static const struct { + const char *psz_id; + const char *psz_name; + enum au_dev au_dev; +} au_devs[] = { + { "PCM", "Up to 9 channels PCM output", AU_DEV_PCM }, + { "ENCODED", "Encoded output if available (via HDMI/SPDIF) or PCM output", + AU_DEV_ENCODED }, +}; + /***************************************************************************** * aout_sys_t: private audio output method descriptor ***************************************************************************** @@ -72,6 +88,7 @@ struct aout_sys_t AudioUnit au_unit; bool b_muted; bool b_preferred_channels_set; + enum au_dev au_dev; }; enum port_type @@ -115,6 +132,10 @@ avas_setPreferredNumberOfChannels(audio_output_t *p_aout, const audio_sample_format_t *fmt) { struct aout_sys_t *p_sys = p_aout->sys; + + if (aout_BitsPerSample(fmt->i_format) == 0) + return; /* Don't touch the number of channels for passthrough */ + AVAudioSession *instance = p_sys->avInstance; NSInteger max_channel_count = [instance maximumOutputNumberOfChannels]; unsigned channel_count = aout_FormatNbChannels(fmt); @@ -356,8 +377,7 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt) OSStatus status; AudioChannelLayout *layout = NULL; - if (aout_FormatNbChannels(fmt) == 0 - || aout_BitsPerSample(fmt->i_format) == 0 /* No Passthrough support */) + if (aout_FormatNbChannels(fmt) == 0 || AOUT_FMT_HDMI(fmt)) return VLC_EGENERIC; aout_FormatPrint(p_aout, "VLC is looking for:", fmt); @@ -377,8 +397,20 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt) if (ret != VLC_SUCCESS) goto error; - /* TODO: Do passthrough if dev_type allows it */ - fmt->i_format = VLC_CODEC_FL32; + if (AOUT_FMT_SPDIF(fmt)) + { + if (p_sys->au_dev != AU_DEV_ENCODED + || (port_type != PORT_TYPE_USB && port_type != PORT_TYPE_HDMI)) + goto error; + + fmt->i_format = VLC_CODEC_SPDIFL; + fmt->i_bytes_per_frame = 4; + fmt->i_frame_length = 1; + free(layout); + layout = NULL; + } + else + fmt->i_format = VLC_CODEC_FL32; p_sys->au_unit = au_NewOutputInstance(p_aout, kAudioUnitSubType_RemoteIO); if (p_sys->au_unit == NULL) @@ -416,7 +448,8 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt) free(layout); p_aout->mute_set = MuteSet; p_aout->pause = Pause; - msg_Dbg(p_aout, "analog AudioUnit output successfully opened"); + msg_Dbg(p_aout, "analog AudioUnit output successfully opened for %4.4s %s", + (const char *)&fmt->i_format, aout_FormatPrintChannels(fmt)); return VLC_SUCCESS; error: @@ -430,6 +463,33 @@ error: return VLC_EGENERIC; } +static int DeviceSelect(audio_output_t *p_aout, const char *psz_id) +{ + aout_sys_t *p_sys = p_aout->sys; + enum au_dev au_dev = AU_DEV_PCM; + + if (psz_id) + { + for (unsigned int i = 0; i < sizeof(au_devs) / sizeof(au_devs[0]); ++i) + { + if (!strcmp(psz_id, au_devs[i].psz_id)) + { + au_dev = au_devs[i].au_dev; + break; + } + } + } + + if (au_dev != p_sys->au_dev) + { + p_sys->au_dev = au_dev; + aout_RestartRequest(p_aout, AOUT_RESTART_OUTPUT); + msg_Dbg(p_aout, "selected audiounit device: %s", psz_id); + } + aout_DeviceReport(p_aout, psz_id); + return VLC_SUCCESS; +} + static void Close(vlc_object_t *obj) { @@ -462,9 +522,14 @@ Open(vlc_object_t *obj) sys->b_muted = false; sys->b_preferred_channels_set = false; + sys->au_dev = AU_DEV_PCM; aout->sys = sys; aout->start = Start; aout->stop = Stop; + aout->device_select = DeviceSelect; + + for (unsigned int i = 0; i< sizeof(au_devs) / sizeof(au_devs[0]); ++i) + aout_HotplugReport(aout, au_devs[i].psz_id, au_devs[i].psz_name); return VLC_SUCCESS; } diff --git a/modules/audio_output/coreaudio_common.c b/modules/audio_output/coreaudio_common.c index 985b770..e3e205a 100644 --- a/modules/audio_output/coreaudio_common.c +++ b/modules/audio_output/coreaudio_common.c @@ -626,25 +626,40 @@ int au_Initialize(audio_output_t *p_aout, AudioUnit au, audio_sample_format_t *fmt, const AudioChannelLayout *outlayout, mtime_t i_dev_latency_us) { - assert(fmt->i_format == VLC_CODEC_FL32); - - int ret = MapOutputLayout(p_aout, fmt, outlayout); - if (ret != VLC_SUCCESS) - return ret; - + int ret; AudioChannelLayoutTag inlayout_tag; - ret = SetupInputLayout(p_aout, fmt, &inlayout_tag); - if (ret != VLC_SUCCESS) - return ret; /* Set the desired format */ AudioStreamBasicDescription desc; + if (fmt->i_format == VLC_CODEC_FL32) + { + ret = MapOutputLayout(p_aout, fmt, outlayout); + if (ret != VLC_SUCCESS) + return ret; + + ret = SetupInputLayout(p_aout, fmt, &inlayout_tag); + if (ret != VLC_SUCCESS) + return ret; + + desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; + desc.mChannelsPerFrame = aout_FormatNbChannels(fmt); + desc.mBitsPerChannel = 32; + } + else + { + /* Passthrough */ + assert(fmt->i_format == VLC_CODEC_SPDIFL); + + inlayout_tag = kAudioChannelLayoutTag_Stereo; + + desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | + kLinearPCMFormatFlagIsPacked; /* S16LE */ + desc.mChannelsPerFrame = 2; + desc.mBitsPerChannel = 16; + } desc.mSampleRate = fmt->i_rate; desc.mFormatID = kAudioFormatLinearPCM; - desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; - desc.mChannelsPerFrame = aout_FormatNbChannels(fmt); desc.mFramesPerPacket = 1; - desc.mBitsPerChannel = 32; desc.mBytesPerFrame = desc.mBitsPerChannel * desc.mChannelsPerFrame / 8; desc.mBytesPerPacket = desc.mBytesPerFrame * desc.mFramesPerPacket; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
