mirror of
https://github.com/mpv-player/mpv
synced 2025-04-24 12:24:21 +00:00
ao_coreaudio: Refactor device selection
Add output device selection and correctly set the default device if it's selected. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31715 b3059339-0415-0410-9bf9-f77b7e298cf2 Fix cosmetics after r31715. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31716 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
2050baef96
commit
2d35ff8332
@ -2804,6 +2804,14 @@ audio output through NAS
|
|||||||
.TP
|
.TP
|
||||||
.B coreaudio (Mac OS X only)
|
.B coreaudio (Mac OS X only)
|
||||||
native Mac OS X audio output driver
|
native Mac OS X audio output driver
|
||||||
|
.PD 0
|
||||||
|
.RSs
|
||||||
|
.IPs device_id=<id>
|
||||||
|
ID of output device to use (0 = default device)
|
||||||
|
.IPs help
|
||||||
|
List all available output devices with their IDs.
|
||||||
|
.RE
|
||||||
|
.PD 1
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
.B "openal\ "
|
.B "openal\ "
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "libaf/af_format.h"
|
#include "libaf/af_format.h"
|
||||||
#include "osdep/timer.h"
|
#include "osdep/timer.h"
|
||||||
#include "libavutil/fifo.h"
|
#include "libavutil/fifo.h"
|
||||||
|
#include "subopt-helper.h"
|
||||||
|
|
||||||
static const ao_info_t info =
|
static const ao_info_t info =
|
||||||
{
|
{
|
||||||
@ -345,6 +346,51 @@ static OSStatus DeviceListener( AudioObjectID inObjectID,
|
|||||||
const AudioObjectPropertyAddress inAddresses[],
|
const AudioObjectPropertyAddress inAddresses[],
|
||||||
void *inClientData );
|
void *inClientData );
|
||||||
|
|
||||||
|
static void print_help(void)
|
||||||
|
{
|
||||||
|
OSStatus err;
|
||||||
|
UInt32 i_param_size;
|
||||||
|
int num_devices;
|
||||||
|
AudioDeviceID *devids;
|
||||||
|
AudioObjectPropertyAddress property_address;
|
||||||
|
char *device_name;
|
||||||
|
|
||||||
|
mp_msg(MSGT_AO, MSGL_FATAL,
|
||||||
|
"\n-ao coreaudio commandline help:\n"
|
||||||
|
"Example: mplayer -ao coreaudio:device_id=266\n"
|
||||||
|
" open Core Audio with output device ID 266.\n"
|
||||||
|
"\nOptions:\n"
|
||||||
|
" device_id\n"
|
||||||
|
" ID of output device to use (0 = default device)\n"
|
||||||
|
" help\n"
|
||||||
|
" This help including list of available devices.\n"
|
||||||
|
"\n"
|
||||||
|
"Available output devices:\n");
|
||||||
|
|
||||||
|
i_param_size = GetGlobalAudioPropertyArray(kAudioObjectSystemObject, kAudioHardwarePropertyDevices, (void **)&devids);
|
||||||
|
|
||||||
|
if (!i_param_size) {
|
||||||
|
mp_msg(MSGT_AO, MSGL_FATAL, "Failed to get list of output devices.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_devices = i_param_size / sizeof(AudioDeviceID);
|
||||||
|
|
||||||
|
for (int i = 0; i < num_devices; ++i) {
|
||||||
|
err = GetAudioPropertyString(devids[i], kAudioObjectPropertyName, &device_name);
|
||||||
|
|
||||||
|
if (err == noErr) {
|
||||||
|
mp_msg(MSGT_AO, MSGL_FATAL, "%s (id: %"PRIu32")\n", device_name, devids[i]);
|
||||||
|
free(device_name);
|
||||||
|
} else
|
||||||
|
mp_msg(MSGT_AO, MSGL_FATAL, "Unknown (id: %"PRIu32")\n", devids[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_msg(MSGT_AO, MSGL_FATAL, "\n");
|
||||||
|
|
||||||
|
free(devids);
|
||||||
|
}
|
||||||
|
|
||||||
static int init(int rate,int channels,int format,int flags)
|
static int init(int rate,int channels,int format,int flags)
|
||||||
{
|
{
|
||||||
AudioStreamBasicDescription inDesc;
|
AudioStreamBasicDescription inDesc;
|
||||||
@ -355,6 +401,20 @@ OSStatus err;
|
|||||||
UInt32 size, maxFrames, i_param_size, b_alive;
|
UInt32 size, maxFrames, i_param_size, b_alive;
|
||||||
char *psz_name;
|
char *psz_name;
|
||||||
AudioDeviceID devid_def = 0;
|
AudioDeviceID devid_def = 0;
|
||||||
|
int device_id;
|
||||||
|
|
||||||
|
const opt_t subopts[] = {
|
||||||
|
{"device_id", OPT_ARG_INT, &device_id, NULL},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
// set defaults
|
||||||
|
device_id = 0;
|
||||||
|
|
||||||
|
if (subopt_parse(ao_subdevice, subopts) != 0) {
|
||||||
|
print_help();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ao_msg(MSGT_AO,MSGL_V, "init([%dHz][%dch][%s][%d])\n", rate, channels, af_fmt2str_short(format), flags);
|
ao_msg(MSGT_AO,MSGL_V, "init([%dHz][%dch][%s][%d])\n", rate, channels, af_fmt2str_short(format), flags);
|
||||||
|
|
||||||
@ -371,9 +431,7 @@ AudioDeviceID devid_def = 0;
|
|||||||
ao->b_revert = 0;
|
ao->b_revert = 0;
|
||||||
ao->b_changed_mixing = 0;
|
ao->b_changed_mixing = 0;
|
||||||
|
|
||||||
/* Probe whether device support S/PDIF stream output if input is AC3 stream. */
|
if (device_id == 0) {
|
||||||
if (AF_FORMAT_IS_AC3(format))
|
|
||||||
{
|
|
||||||
/* Find the ID of the default Device. */
|
/* Find the ID of the default Device. */
|
||||||
err = GetAudioProperty(kAudioObjectSystemObject,
|
err = GetAudioProperty(kAudioObjectSystemObject,
|
||||||
kAudioHardwarePropertyDefaultOutputDevice,
|
kAudioHardwarePropertyDefaultOutputDevice,
|
||||||
@ -383,29 +441,36 @@ AudioDeviceID devid_def = 0;
|
|||||||
ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device: [%4.4s]\n", (char *)&err);
|
ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device: [%4.4s]\n", (char *)&err);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
devid_def = device_id;
|
||||||
|
}
|
||||||
|
|
||||||
/* Retrieve the name of the device. */
|
/* Retrieve the name of the device. */
|
||||||
err = GetAudioPropertyString(devid_def,
|
err = GetAudioPropertyString(devid_def,
|
||||||
kAudioObjectPropertyName,
|
kAudioObjectPropertyName,
|
||||||
&psz_name);
|
&psz_name);
|
||||||
if (err != noErr)
|
if (err != noErr)
|
||||||
{
|
{
|
||||||
ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device name: [%4.4s]\n", (char *)&err);
|
ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device name: [%4.4s]\n", (char *)&err);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ao_msg(MSGT_AO,MSGL_V, "got default audio output device ID: %"PRIu32" Name: %s\n", devid_def, psz_name );
|
ao_msg(MSGT_AO,MSGL_V, "got audio output device ID: %"PRIu32" Name: %s\n", devid_def, psz_name );
|
||||||
|
|
||||||
|
/* Probe whether device support S/PDIF stream output if input is AC3 stream. */
|
||||||
|
if (AF_FORMAT_IS_AC3(format)) {
|
||||||
if (AudioDeviceSupportsDigital(devid_def))
|
if (AudioDeviceSupportsDigital(devid_def))
|
||||||
{
|
{
|
||||||
ao->b_supports_digital = 1;
|
ao->b_supports_digital = 1;
|
||||||
ao->i_selected_dev = devid_def;
|
|
||||||
}
|
}
|
||||||
ao_msg(MSGT_AO,MSGL_V, "probe default audio output device whether support digital s/pdif output:%d\n", ao->b_supports_digital );
|
ao_msg(MSGT_AO,MSGL_V, "probe default audio output device whether support digital s/pdif output:%d\n", ao->b_supports_digital );
|
||||||
|
|
||||||
free( psz_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(psz_name);
|
||||||
|
|
||||||
|
// Save selected device id
|
||||||
|
ao->i_selected_dev = devid_def;
|
||||||
|
|
||||||
// Build Description for the input format
|
// Build Description for the input format
|
||||||
inDesc.mSampleRate=rate;
|
inDesc.mSampleRate=rate;
|
||||||
inDesc.mFormatID=ao->b_supports_digital ? kAudioFormat60958AC3 : kAudioFormatLinearPCM;
|
inDesc.mFormatID=ao->b_supports_digital ? kAudioFormat60958AC3 : kAudioFormatLinearPCM;
|
||||||
@ -441,6 +506,7 @@ AudioDeviceID devid_def = 0;
|
|||||||
ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is alive: [%4.4s]\n", (char *)&err);
|
ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is alive: [%4.4s]\n", (char *)&err);
|
||||||
if (!b_alive)
|
if (!b_alive)
|
||||||
ao_msg(MSGT_AO, MSGL_WARN, "device is not alive\n" );
|
ao_msg(MSGT_AO, MSGL_WARN, "device is not alive\n" );
|
||||||
|
|
||||||
/* S/PDIF output need device in HogMode. */
|
/* S/PDIF output need device in HogMode. */
|
||||||
err = GetAudioProperty(ao->i_selected_dev,
|
err = GetAudioProperty(ao->i_selected_dev,
|
||||||
kAudioDevicePropertyHogMode,
|
kAudioDevicePropertyHogMode,
|
||||||
@ -464,7 +530,7 @@ AudioDeviceID devid_def = 0;
|
|||||||
|
|
||||||
/* original analog output code */
|
/* original analog output code */
|
||||||
desc.componentType = kAudioUnitType_Output;
|
desc.componentType = kAudioUnitType_Output;
|
||||||
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
|
desc.componentSubType = (device_id == 0) ? kAudioUnitSubType_DefaultOutput : kAudioUnitSubType_HALOutput;
|
||||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||||
desc.componentFlags = 0;
|
desc.componentFlags = 0;
|
||||||
desc.componentFlagsMask = 0;
|
desc.componentFlagsMask = 0;
|
||||||
@ -505,6 +571,9 @@ AudioDeviceID devid_def = 0;
|
|||||||
goto err_out2;
|
goto err_out2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Set the Current Device to the Default Output Unit.
|
||||||
|
err = AudioUnitSetProperty(ao->theOutputUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &ao->i_selected_dev, sizeof(ao->i_selected_dev));
|
||||||
|
|
||||||
ao->chunk_size = maxFrames;//*inDesc.mBytesPerFrame;
|
ao->chunk_size = maxFrames;//*inDesc.mBytesPerFrame;
|
||||||
|
|
||||||
ao_data.samplerate = inDesc.mSampleRate;
|
ao_data.samplerate = inDesc.mSampleRate;
|
||||||
@ -547,11 +616,11 @@ err_out:
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static int OpenSPDIF(void)
|
static int OpenSPDIF(void)
|
||||||
{
|
{
|
||||||
OSStatus err = noErr;
|
OSStatus err = noErr;
|
||||||
UInt32 i_param_size, b_mix = 0;
|
UInt32 i_param_size, b_mix = 0;
|
||||||
Boolean b_writeable = 0;
|
Boolean b_writeable = 0;
|
||||||
AudioStreamID *p_streams = NULL;
|
AudioStreamID *p_streams = NULL;
|
||||||
int i, i_streams = 0;
|
int i, i_streams = 0;
|
||||||
AudioObjectPropertyAddress property_address;
|
AudioObjectPropertyAddress property_address;
|
||||||
|
|
||||||
/* Start doing the SPDIF setup process. */
|
/* Start doing the SPDIF setup process. */
|
||||||
|
Loading…
Reference in New Issue
Block a user