This makes avdevice_list_input_sources() available for device_name = "avfoundation".
I didn't yet retrofit avf_read_header() to use the new function to keep this patch small. Signed-off-by: Daniel Ly <nal...@gmail.com> --- libavdevice/avfoundation.m | 85 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m index 763e675..523dc12 100644 --- a/libavdevice/avfoundation.m +++ b/libavdevice/avfoundation.m @@ -34,6 +34,7 @@ #include "libavformat/internal.h" #include "libavutil/internal.h" #include "libavutil/parseutils.h" +#include "libavutil/avstring.h" #include "libavutil/time.h" #include "avdevice.h" @@ -1007,6 +1008,89 @@ static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) return 0; } +static int avf_add_device_info( + AVDeviceInfoList *list, int index, const char *description, const char *model +) +{ + AVDeviceInfo *info = av_mallocz(sizeof(AVDeviceInfo)); + if (!info) return AVERROR(ENOMEM); + + info->device_name = av_asprintf("[%d] %s; %s", index, description, model); + info->device_description = strdup(description); + if (!info->device_name || !info->device_description) { + av_free(info); + return AVERROR(ENOMEM); + } + + av_dynarray_add(&list->devices, &list->nb_devices, info); + return list ? list->nb_devices : AVERROR(ENOMEM); +} + + +static int avf_get_device_list( + struct AVFormatContext *s, struct AVDeviceInfoList *list +) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + uint32_t num_screens = 0; + AVFContext *ctx = (AVFContext*)s->priv_data; + NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + +#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + CGGetActiveDisplayList(0, NULL, &num_screens); +#endif + + int result = 0; + int index; + const char *localizedName, *modelID; + + av_log(ctx, AV_LOG_INFO, "AVFoundation video devices:\n"); + for (AVCaptureDevice *device in devices) { + index = [devices indexOfObject:device]; + localizedName = [[device localizedName] UTF8String]; + modelID = [[device modelID] UTF8String]; + result = avf_add_device_info(list, index, localizedName, modelID); + if (result < 0) goto fail; + av_log(ctx, AV_LOG_INFO, "%s\n", list->devices[result - 1]->device_name); + } +#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + if (num_screens > 0) { + CGDirectDisplayID screens[num_screens]; + CGGetActiveDisplayList(num_screens, screens, &num_screens); + for (int i = 0; i < num_screens; i++) { + char buf[30]; + snprintf(buf, 30, "Capture screen %d", i); + + // No screen name available. Implementation is arcane and uses + // deprecated API, see http://stackoverflow.com/q/24348142/220060. + // Perhaps the current screen resolution would be more interesting. + result = avf_add_device_info(list, index + i + 1, buf, "-"); + if (result < 0) goto fail; + av_log(ctx, AV_LOG_INFO, "%s\n", list->devices[result - 1]->device_name); + } + } +#endif + + av_log(ctx, AV_LOG_INFO, "AVFoundation audio devices:\n"); + devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio]; + for (AVCaptureDevice *device in devices) { + index = [devices indexOfObject:device]; + localizedName = [[device localizedName] UTF8String]; + modelID = [[device modelID] UTF8String]; + result = avf_add_device_info(list, index, localizedName, modelID); + if (result < 0) goto fail; + av_log(ctx, AV_LOG_INFO, "%s\n", list->devices[result - 1]->device_name); + } + + list->default_device = 0; + +fail: + [pool release]; + destroy_context(ctx); + + return result; +} + static int avf_close(AVFormatContext *s) { AVFContext* ctx = (AVFContext*)s->priv_data; @@ -1044,6 +1128,7 @@ AVInputFormat ff_avfoundation_demuxer = { .read_header = avf_read_header, .read_packet = avf_read_packet, .read_close = avf_close, + .get_device_list= avf_get_device_list, .flags = AVFMT_NOFILE, .priv_class = &avf_class, }; -- 1.8.1.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel