From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 19F6D42399 for ; Fri, 17 Dec 2021 21:52:10 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 42C4668AEBA; Fri, 17 Dec 2021 23:52:08 +0200 (EET) Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C026F680529 for ; Fri, 17 Dec 2021 23:52:01 +0200 (EET) Received: by mail-wr1-f42.google.com with SMTP id r17so6172215wrc.3 for ; Fri, 17 Dec 2021 13:52:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version; bh=q1yIo52EwFavrOZfG7QAIitUeSgQ51+H9r7GLmpx/1g=; b=bfU80gQ2MCEXrEqIKTruX7TjXC8Zx71gqNcFlz+FdOLsnorXbiIvbIAn/FpFaYKq6k kdCrG/SybT3PDMYXAR/j3EETPduRXAhIK2DutOqemttWPrbLr73SSw+qAFCJyMIe14Gs UFiSfB1GSPgpConNeukvlMJllbwkPs97mOHdrfJ9uA1y2aKoLJwZqhxQg6REUHM3zFJR Doa9OzsiHXc5zAlsaqXFP7FO5WLqAAWjlDrOeKihfUbL9pNvl9MQ7NbO8f+/bWZ1dgP8 +krgKje50/tbYQZ5cOhHIJ8CZSvFGSDwhoTGI13h95NvXQC4GX6+MwxvgL6vpdBGOK2d BlIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version; bh=q1yIo52EwFavrOZfG7QAIitUeSgQ51+H9r7GLmpx/1g=; b=U1zg9KUNCNPrSA6oisMDH5FQv/qWjN+qDEe/Esnk4OoSKCBNVQDRiUSn/jawmeX6nq zEOF2s2L5fsSrOJBXOsv9JHhCi9W5IDkwmq1XkuOXrchGacAi2CBaFvP+oJFwuBTunSy KAgQERBPuVAZI01n1AEit7tkVJcCb2lUr0m1E0uiLRsaFlCA1yNEyvbaaNy749dt6WkW Xqw4YbjdXAdgoten6kRbWU9Lf+I0ZV1uNwOnvUZMyeowtvF7RW/WMzSiNjrRKkCrMYX5 yplma7/WeJYAzb941f+QVciesslX+Id9CJgJahiNpkpDGvRYU9M6Nqg7ntvKQBVuyq/T +wYw== X-Gm-Message-State: AOAM53172l+SIkxawrdPp1210OMhxPcgLqyujCdQzRJe1v7vfQ4Iw7p2 Xp6eZs9pnadpkqsC1gzB9dAP9JcDE+EK4g== X-Google-Smtp-Source: ABdhPJyLWfihCENTnGIeOZ7B+CmOZ4iLTscZOAR66mn/4+acxZlzsAG1M2C/kG8ontvr1Wwx0WfaCA== X-Received: by 2002:adf:9d8c:: with SMTP id p12mr3997064wre.622.1639777920738; Fri, 17 Dec 2021 13:52:00 -0800 (PST) Received: from [10.10.10.172] (84-112-75-55.cable.dynamic.surfer.at. [84.112.75.55]) by smtp.gmail.com with ESMTPSA id m3sm2040457wms.25.2021.12.17.13.52.00 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Dec 2021 13:52:00 -0800 (PST) From: "Marvin Scholz" To: "FFmpeg development discussions and patches" Date: Fri, 17 Dec 2021 22:51:59 +0100 X-Mailer: MailMate (1.13.2r5673) Message-ID: In-Reply-To: References: MIME-Version: 1.0 Subject: Re: [FFmpeg-devel] [PATCH v4 3/3] libavdevice/avfoundation.m: Allow to select devices by unique ID. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii"; Format="flowed" Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: On 17 Dec 2021, at 16:12, Romain Beauxis wrote: > This is the third patch of a series of 3 that cleanup and enhance the > avfoundation implementation for libavdevice. > > Changes: > v2: None > v3: > * Switched unique ID to use system-prodvided unique ID > * Implemented unique IDs for screen capture > v4: Cleanup > > This patch adds a unique ID to avfoundation devices. This is needed > because device index can change while the machine is running when > devices are plugged or unplugged and device names can be tricky to use > with localization and etc. > > Example of output: > ./ffmpeg -f avfoundation -list_devices true -i "" > [...] > [AVFoundation indev @ 0x158705230] AVFoundation video devices: > [AVFoundation indev @ 0x158705230] [0] FaceTime HD Camera (ID: > 47B4B64B70674B9CAD2BAE273A71F4B5) > [AVFoundation indev @ 0x158705230] [1] Capture screen 0 (ID: > AvfilterAvfoundationCaptureScreen1) > [AVFoundation indev @ 0x158705230] AVFoundation audio devices: > [AVFoundation indev @ 0x158705230] [0] Loopback Audio (ID: > com.rogueamoeba.Loopback.A5668B36-711E-4DF5-8A8D-7148508C735B) > [AVFoundation indev @ 0x158705230] [1] MacBook Pro Microphone (ID: > BuiltInMicrophoneDevice) > > Notes: > * Unique names do not seem to follow any specific pattern. I have used > one similar to the builtin microphone for screen capture > * The : substitution is actually required. The loopback device above > did > have it in its name. > Is there no way to escape the : in the command so that we would not need to mess with the ID the system gives us? And if we need to, it would be ideal to have a fully reversible way of doing so, as then you could just reverse the mangling and use `deviceWithUniqueID:` instead of iterating all devices. That said, if thats not easily doable I am fine with the patch as-is, aside from the minor comments below, thanks for your work on this. > Signed-off-by: Romain Beauxis > --- > doc/indevs.texi | 6 ++-- > libavdevice/avfoundation.m | 72 > +++++++++++++++++++++++++++++--------- > 2 files changed, 60 insertions(+), 18 deletions(-) > > diff --git a/doc/indevs.texi b/doc/indevs.texi > index 5be647f70a..2b55399c8c 100644 > --- a/doc/indevs.texi > +++ b/doc/indevs.texi > @@ -114,7 +114,7 @@ The input filename has to be given in the > following syntax: > -i "[[VIDEO]:[AUDIO]]" > @end example > The first entry selects the video input while the latter selects the > audio input. > -The stream has to be specified by the device name or the device index > as shown by the device list. > +The stream has to be specified by the device name, index or ID as > shown by the device list. > Alternatively, the video and/or audio input device can be chosen by > index using the > @option{ > -video_device_index > @@ -127,7 +127,9 @@ and/or > device name or index given in the input filename. > All available devices can be enumerated by using > @option{-list_devices true}, listing > -all device names and corresponding indices. > +all device names, corresponding indices and IDs, when available. > Device name can be +tricky to use when localized and device index can > change when devices are plugged or unplugged. A device > +hash, when available, uniquely identifies a device and should not > change over time. This should say ID I think, as hash was never mentioned before. > There are two device name aliases: > @table @code > diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m > index b602cfbe95..25286507d6 100644 > --- a/libavdevice/avfoundation.m > +++ b/libavdevice/avfoundation.m > @@ -39,6 +39,8 @@ > #include "libavutil/imgutils.h" > #include "avdevice.h" > +#define CLEANUP_DEVICE_ID(s) [[s > stringByReplacingOccurrencesOfString:@":" withString:@"."] UTF8String] > + > static const int avf_time_base = 1000000; > static const AVRational avf_time_base_q = { > @@ -797,21 +799,23 @@ static int avf_read_header(AVFormatContext *s) > int index = 0; > av_log(ctx, AV_LOG_INFO, "AVFoundation video devices:\n"); > for (AVCaptureDevice *device in devices) { > - const char *name = [[device localizedName] UTF8String]; > - index = [devices indexOfObject:device]; > - av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name); > + const char *name = [[device localizedName] > UTF8String]; > + const char *uniqueId = CLEANUP_DEVICE_ID([device > uniqueID]); > + index = [devices indexOfObject:device]; > + av_log(ctx, AV_LOG_INFO, "[%d] %s (ID: %s)\n", index, > name, uniqueId); > } > for (AVCaptureDevice *device in devices_muxed) { > - const char *name = [[device localizedName] UTF8String]; > - index = [devices count] + [devices_muxed > indexOfObject:device]; > - av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name); > + const char *name = [[device localizedName] > UTF8String]; > + const char *uniqueId = CLEANUP_DEVICE_ID([device > uniqueID]); > + index = [devices count] + [devices_muxed > indexOfObject:device]; > + av_log(ctx, AV_LOG_INFO, "[%d] %s (ID: %s)\n", index, > name, uniqueId); > } > #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++) { > - av_log(ctx, AV_LOG_INFO, "[%d] Capture screen %d\n", > ctx->num_video_devices + i, i); > + av_log(ctx, AV_LOG_INFO, "[%d] Capture screen %d (ID: > AvfilterAvfoundationCaptureScreen%d)\n", ctx->num_video_devices + i, > i, screens[i]); > } > } > #endif > @@ -819,9 +823,10 @@ static int avf_read_header(AVFormatContext *s) > av_log(ctx, AV_LOG_INFO, "AVFoundation audio devices:\n"); > devices = [AVCaptureDevice > devicesWithMediaType:AVMediaTypeAudio]; > for (AVCaptureDevice *device in devices) { > - const char *name = [[device localizedName] UTF8String]; > - int index = [devices indexOfObject:device]; > - av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name); > + const char *name = [[device localizedName] > UTF8String]; > + const char *uniqueId = CLEANUP_DEVICE_ID([device > uniqueID]); > + int index = [devices indexOfObject:device]; > + av_log(ctx, AV_LOG_INFO, "[%d] %s (ID: %s)\n", index, > name, uniqueId); > } > goto fail; > } > @@ -883,14 +888,29 @@ static int avf_read_header(AVFormatContext *s) > } else { > // looking for video inputs > for (AVCaptureDevice *device in devices) { > - if (!strncmp(ctx->video_filename, [[device localizedName] > UTF8String], strlen(ctx->video_filename))) { > + const char *name = [[device localizedName] UTF8String]; > + if (!strncmp(ctx->video_filename, name, > strlen(ctx->video_filename))) { > + video_device = device; > + break; > + } > + > + const char *uniqueId = CLEANUP_DEVICE_ID([device > uniqueID]); > + if (!strncmp(ctx->video_filename, uniqueId, > strlen(ctx->video_filename))) { > video_device = device; > break; > } > } > // looking for muxed inputs > for (AVCaptureDevice *device in devices_muxed) { > - if (!strncmp(ctx->video_filename, [[device localizedName] > UTF8String], strlen(ctx->video_filename))) { > + const char *name = [[device localizedName] UTF8String]; > + if (!strncmp(ctx->video_filename, name, > strlen(ctx->video_filename))) { > + video_device = device; > + ctx->video_is_muxed = 1; > + break; > + } > + > + const char *uniqueId = CLEANUP_DEVICE_ID([device > uniqueID]); > + if (!strncmp(ctx->video_filename, uniqueId, > strlen(ctx->video_filename))) { > video_device = device; > ctx->video_is_muxed = 1; > break; > @@ -901,10 +921,23 @@ static int avf_read_header(AVFormatContext *s) > // looking for screen inputs > if (!video_device) { > int idx; > + CGDirectDisplayID screens[num_screens]; > + CGGetActiveDisplayList(num_screens, screens, > &num_screens); > + AVCaptureScreenInput* capture_screen_input = NULL; > + > if(sscanf(ctx->video_filename, "Capture screen %d", &idx) > && idx < num_screens) { > - CGDirectDisplayID screens[num_screens]; > - CGGetActiveDisplayList(num_screens, screens, > &num_screens); > - AVCaptureScreenInput* capture_screen_input = > [[[AVCaptureScreenInput alloc] initWithDisplayID:screens[idx]] > autorelease]; > + capture_screen_input = [[[AVCaptureScreenInput alloc] > initWithDisplayID:screens[idx]] autorelease]; > + } > + > + if(sscanf(ctx->video_filename, > "AvfilterAvfoundationCaptureScreen%d", &idx)) { > + for (int i = 0; i < num_screens; i++) { > + if (screens[i] == idx) { > + capture_screen_input = > [[[AVCaptureScreenInput alloc] initWithDisplayID:idx] autorelease]; > + } > + } > + } > + > + if (capture_screen_input) { > video_device = (AVCaptureDevice*) > capture_screen_input; > ctx->video_device_index = ctx->num_video_devices + > idx; > ctx->video_is_screen = 1; > @@ -955,7 +988,14 @@ static int avf_read_header(AVFormatContext *s) > NSArray *devices = [AVCaptureDevice > devicesWithMediaType:AVMediaTypeAudio]; > for (AVCaptureDevice *device in devices) { > - if (!strncmp(ctx->audio_filename, [[device localizedName] > UTF8String], strlen(ctx->audio_filename))) { > + const char *name = [[device localizedName] UTF8String]; > + if (!strncmp(ctx->audio_filename, name, > strlen(ctx->audio_filename))) { > + audio_device = device; > + break; > + } > + > + const char *uniqueId = CLEANUP_DEVICE_ID([device > uniqueID]); > + if (!strncmp(ctx->audio_filename, uniqueId, > strlen(ctx->audio_filename))) { > audio_device = device; > break; > } > -- > 2.32.0 (Apple Git-132) > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".