28 #import <AudioToolbox/AudioToolbox.h>
52 if (*status != noErr) {
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;
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",
Main libavdevice API header.
#define pthread_mutex_lock(a)
#define pthread_mutex_unlock(a)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
#define LIBAVUTIL_VERSION_INT
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
@ AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT
#define AV_OPT_FLAG_ENCODING_PARAM
a generic parameter which can be set by the user for muxing or encoding
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Describe the class of an AVClass context structure.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
This struct describes the properties of an encoded stream.
enum AVMediaType codec_type
General type of the encoded data.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
int sample_rate
Audio only.
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
char * url
input or output URL.
void * priv_data
Format private data.
AVStream ** streams
A list of all streams in the file.
This structure stores compressed data.
AVCodecParameters * codecpar
Codec parameters associated with this stream.