Am 23.04.15 um 09:35 schrieb Daniel Ly: > 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.
Please post a follow-up patch for that purpose, too. (In that thread) > 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 > +) Paranthesis looks awkward. > +{ > + AVDeviceInfo *info = av_mallocz(sizeof(AVDeviceInfo)); > + if (!info) return AVERROR(ENOMEM); > + > + info->device_name = av_asprintf("[%d] %s; %s", index, description, > model); Is this string format kind of standard in FFmpeg? Otherwise I would prefer description behind model and no ';' but a ':'. > + 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); I'm not sure if "list" is null'd in case of an error in av_dynarray_add? > +} > + > + > +static int avf_get_device_list( > + struct AVFormatContext *s, struct AVDeviceInfoList *list > +) See above... > +{ > + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; > + uint32_t num_screens = 0; > + AVFContext *ctx = (AVFContext*)s->priv_data; > + NSArray *devices = [AVCaptureDevice > devicesWithMediaType:AVMediaTypeVideo]; Please align vertically even if one line gets too long by that. > + > +#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); Vertical alignment. > + if (result < 0) goto fail; > + av_log(ctx, AV_LOG_INFO, "%s\n", list->devices[result - > 1]->device_name); Segfault if result == 0? > + } > +#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, > }; > -Thilo _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel