On Thu, Apr 23, 2015 at 9:58 AM, Thilo Borgmann <thilo.borgm...@mail.de> wrote:
> 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) Ok. > > 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. > I moved the parenthesis to the end of the previous line. > > +{ > > + 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 ':'. > I replaced ; by :. ffmpeg -f avfoundation -list_devices true -i dummy produces this output: [AVFoundation input device @ 0x7fec68c01080] AVFoundation video devices: [AVFoundation input device @ 0x7fec68c01080] [0] Logitech Camera [AVFoundation input device @ 0x7fec68c01080] [1] Capture screen 0 [AVFoundation input device @ 0x7fec68c01080] [2] Capture screen 1 [AVFoundation input device @ 0x7fec68c01080] AVFoundation audio devices: [AVFoundation input device @ 0x7fec68c01080] [0] Logitech Camera [AVFoundation input device @ 0x7fec68c01080] [1] Built-in Input Now it looks like this: [AVFoundation input device @ 0x7fdcd9421830] AVFoundation video devices: [AVFoundation input device @ 0x7fdcd9421830] [0] Logitech Camera: UVC Camera VendorID_1133 ProductID_2050 [AVFoundation input device @ 0x7fdcd9421830] [1] Capture screen 0: - [AVFoundation input device @ 0x7fdcd9421830] [2] Capture screen 1: - [AVFoundation input device @ 0x7fdcd9421830] AVFoundation audio devices: [AVFoundation input device @ 0x7fdcd9421830] [0] Logitech Camera: UVC Camera VendorID_1133 ProductID_2050 Doxygen says about the struct AVDeviceInfo that device_name is device name, format depends on device; and that device_description is human friendly name. Therefore I set device_description to "Logitech Camera" and device_name to = "Logitech Camera: UVC Camera VendorID_1133 ProductID_2050". This is awkward but I don't know what else to put in. > + 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? > Doxygen says: In case of failure, the array is freed, *tab_ptr is set to NULL and *nb_ptr is set to 0. > > +} > > + > > + > > +static int avf_get_device_list( > > + struct AVFormatContext *s, struct AVDeviceInfoList *list > > +) > > See above... > Ok. > > +{ > > + 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. > Ok. > > + > > +#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. > Ok. Also aligned lines 1122-1130. > > + if (result < 0) goto fail; > > + av_log(ctx, AV_LOG_INFO, "%s\n", list->devices[result - > 1]->device_name); > > Segfault if result == 0? > Does not matter. I switched to @autoreleasepool {} and removed the fail label. valgrind and I are happier with the memory leaks. > > + } > > +#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 > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel