28 #import <AudioToolbox/AudioToolbox.h>
62 AudioQueueBufferRef inBuffer)
66 for (
int i = 0;
i < 2;
i++) {
67 if (inBuffer ==
ctx->buffer[
i]) {
77 CFStringRef device_UID =
NULL;
78 AudioDeviceID *devices;
84 AudioObjectPropertyAddress prop;
85 prop.mSelector = kAudioHardwarePropertyDevices;
86 prop.mScope = kAudioObjectPropertyScopeGlobal;
87 prop.mElement = kAudioObjectPropertyElementMaster;
88 err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &prop, 0,
NULL, &data_size);
89 if (
check_status(avctx, &err,
"AudioObjectGetPropertyDataSize devices"))
92 num_devices = data_size /
sizeof(AudioDeviceID);
94 devices = (AudioDeviceID*)(
av_malloc(data_size));
95 err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop, 0,
NULL, &data_size, devices);
96 if (
check_status(avctx, &err,
"AudioObjectGetPropertyData devices")) {
102 if (
ctx->list_devices) {
103 CFStringRef device_name =
NULL;
104 prop.mScope = kAudioDevicePropertyScopeInput;
107 for(UInt32
i = 0;
i < num_devices; ++
i) {
109 data_size =
sizeof(device_UID);
110 prop.mSelector = kAudioDevicePropertyDeviceUID;
111 err = AudioObjectGetPropertyData(devices[
i], &prop, 0,
NULL, &data_size, &device_UID);
112 if (
check_status(avctx, &err,
"AudioObjectGetPropertyData UID"))
116 data_size =
sizeof(device_name);
117 prop.mSelector = kAudioDevicePropertyDeviceNameCFString;
118 err = AudioObjectGetPropertyData(devices[
i], &prop, 0,
NULL, &data_size, &device_name);
119 if (
check_status(avctx, &err,
"AudioObjecTGetPropertyData name"))
123 CFStringGetCStringPtr(device_name, kCFStringEncodingMacRoman),
124 CFStringGetCStringPtr(device_UID, kCFStringEncodingMacRoman));
130 const char *stream_name = avctx->
url;
131 if (stream_name &&
ctx->audio_device_index == -1) {
132 sscanf(stream_name,
"%d", &
ctx->audio_device_index);
135 if (
ctx->audio_device_index >= 0) {
137 data_size =
sizeof(device_UID);
138 prop.mSelector = kAudioDevicePropertyDeviceUID;
139 err = AudioObjectGetPropertyData(devices[
ctx->audio_device_index], &prop, 0,
NULL, &data_size, &device_UID);
140 if (
check_status(avctx, &err,
"AudioObjecTGetPropertyData UID")) {
151 av_log(
ctx,
AV_LOG_DEBUG,
"UID: %s\n", CFStringGetCStringPtr(device_UID, kCFStringEncodingMacRoman));
163 AudioStreamBasicDescription device_format = {0};
165 device_format.mFormatID = kAudioFormatLinearPCM;
176 device_format.mChannelsPerFrame = codecpar->channels;
178 device_format.mBytesPerFrame = (device_format.mBitsPerChannel >> 3) * device_format.mChannelsPerFrame;
179 device_format.mFramesPerPacket = 1;
180 device_format.mBytesPerPacket = device_format.mBytesPerFrame * device_format.mFramesPerPacket;
181 device_format.mReserved = 0;
198 av_log(
ctx,
AV_LOG_DEBUG,
"device_format.mBytesPerFrame = %i\n", (device_format.mBitsPerChannel >> 3) * codecpar->channels);
205 NULL, kCFRunLoopCommonModes,
208 if (err == kAudioFormatUnsupportedDataFormatError)
214 if (device_UID !=
NULL) {
215 err = AudioQueueSetProperty(
ctx->queue, kAudioQueueProperty_CurrentDevice, &device_UID,
sizeof(device_UID));
216 if (
check_status(avctx, &err,
"AudioQueueSetProperty output UID"))
221 err = AudioQueueStart(
ctx->queue,
NULL);
235 OSStatus err = noErr;
238 ctx->cur_buf = !
ctx->cur_buf;
245 if (!
ctx->buffer[
ctx->cur_buf] ||
ctx->buffer[
ctx->cur_buf]->mAudioDataBytesCapacity !=
pkt->
size) {
246 err = AudioQueueAllocateBuffer(
ctx->queue,
pkt->
size, &
ctx->buffer[
ctx->cur_buf]);
247 if (
check_status(avctx, &err,
"AudioQueueAllocateBuffer")) {
253 AudioQueueBufferRef buf =
ctx->buffer[ctx->
cur_buf];
256 memcpy(buf->mAudioData,
pkt->
data, buf->mAudioDataBytesCapacity);
257 buf->mAudioDataByteSize = buf->mAudioDataBytesCapacity;
258 err = AudioQueueEnqueueBuffer(
ctx->queue, buf, 0,
NULL);
259 if (
check_status(avctx, &err,
"AudioQueueEnqueueBuffer")) {
270 OSStatus err = noErr;
275 err = AudioQueueFlush(
ctx->queue);
277 err = AudioQueueDispose(
ctx->queue,
true);
298 .
name =
"audiotoolbox",