CoreAudioCaptureDevice.cpp [plain text]
#include "config.h"
#include "CoreAudioCaptureDevice.h"
#if ENABLE(MEDIA_STREAM) && PLATFORM(MAC)
#include "CaptureDeviceManager.h"
#include "Logging.h"
#include <AudioUnit/AudioUnit.h>
#include <CoreMedia/CMSync.h>
#import <pal/cf/CoreMediaSoftLink.h>
namespace WebCore {
using namespace PAL;
static bool getDeviceInfo(uint32_t deviceID, String& persistentID, String& label)
{
CFStringRef uniqueID;
AudioObjectPropertyAddress address { kAudioDevicePropertyDeviceUID, kAudioDevicePropertyScopeInput, kAudioObjectPropertyElementMaster };
UInt32 dataSize = sizeof(uniqueID);
auto err = AudioObjectGetPropertyData(static_cast<UInt32>(deviceID), &address, 0, nullptr, &dataSize, &uniqueID);
if (err) {
LOG(Media, "CoreAudioCaptureDevice::getDeviceInfo failed to get device unique id with error %d (%.4s)", (int)err, (char*)&err);
return false;
}
persistentID = uniqueID;
CFRelease(uniqueID);
CFStringRef localizedName;
address = { kAudioObjectPropertyName, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
dataSize = sizeof(localizedName);
err = AudioObjectGetPropertyData(static_cast<UInt32>(deviceID), &address, 0, nullptr, &dataSize, &localizedName);
if (err) {
LOG(Media, "CoreAudioCaptureDevice::getDeviceInfo failed to get device name with error %d (%.4s)", (int)err, (char*)&err);
return false;
}
label = localizedName;
CFRelease(localizedName);
return true;
}
std::optional<CoreAudioCaptureDevice> CoreAudioCaptureDevice::create(uint32_t deviceID)
{
String persistentID;
String label;
if (!getDeviceInfo(deviceID, persistentID, label))
return std::nullopt;
return CoreAudioCaptureDevice(deviceID, persistentID, label);
}
CoreAudioCaptureDevice::CoreAudioCaptureDevice(uint32_t deviceID, const String& persistentID, const String& label)
: CaptureDevice(persistentID, CaptureDevice::DeviceType::Microphone, label)
, m_deviceID(deviceID)
{
}
RetainPtr<CMClockRef> CoreAudioCaptureDevice::deviceClock()
{
if (m_deviceClock)
return m_deviceClock;
CMClockRef clock;
auto err = CMAudioDeviceClockCreate(kCFAllocatorDefault, persistentId().createCFString().get(), &clock);
if (err) {
LOG(Media, "CoreAudioCaptureDevice::CMAudioDeviceClockCreate(%p) CMAudioDeviceClockCreate failed with error %d (%.4s)", this, (int)err, (char*)&err);
return nullptr;
}
m_deviceClock = adoptCF(clock);
return m_deviceClock;
}
bool CoreAudioCaptureDevice::isAlive()
{
AudioObjectPropertyAddress address = { kAudioDevicePropertyDeviceIsAlive, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
UInt32 state = 0;
UInt32 dataSize = sizeof(state);
if (AudioObjectGetPropertyData(static_cast<UInt32>(m_deviceID), &address, 0, nullptr, &dataSize, &state))
return false;
return state;
}
}
#endif // ENABLE(MEDIA_STREAM) && PLATFORM(MAC)