On 13 Dec 2021, at 17:40, Romain Beauxis wrote:

This is the third patch of a series of 3 that cleanup and enhance the
avfoundation implementation for libavdevice.

This patch adds a digest to avfoundation devices, when available. 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.

The only device type that are excluded are screen capture because the logic to select them seems a little different and I wanted to minimized the changes. Also, for these devices, the name is localized in english, quite straight forward and should not change.

Signed-off-by: Romain Beauxis <to...@rastageeks.org>
---


Hi,
thanks for the patch, however I fail to see the benefit of it.
You mention that using the name is complicated because it is localized,
but your patch just seems to use the device name and hashes it, which
does not mitigate the issues with the localized name (that could change
when the language is changed) but just hides it behind a hash, making
this problem even more obscure and confusing.
(Correct me if I read your patch wrong, but it seems to just do that.)

Instead I think that you should use the uniqueID property of an AVCaptureDevice,
documented here:
https://developer.apple.com/documentation/avfoundation/avcapturedevice/1390477-uniqueid?language=objc

According to the docs, this seems more appropriated, as it does not depend on the localization and does not change when the device is unplugged and re-plugged.

Regards,
Marvin Scholz

doc/indevs.texi            |  6 ++--
libavdevice/avfoundation.m | 60 ++++++++++++++++++++++++++++++++++----
2 files changed, 58 insertions(+), 8 deletions(-)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index 5be647f70a..8345b64a28 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 digest 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 <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 digests, 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.

There are two device name aliases:
@table @code
diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m
index 95414fd16a..bede51bda0 100644
--- a/libavdevice/avfoundation.m
+++ b/libavdevice/avfoundation.m
@@ -26,6 +26,7 @@
 */

#import <AVFoundation/AVFoundation.h>
+#import <CommonCrypto/CommonDigest.h>

#include "libavutil/channel_layout.h"
#include "libavutil/pixdesc.h"
@@ -79,6 +80,28 @@
    { AV_PIX_FMT_NONE, 0 }
};

+#define DEVICES_DIGEST_LENGTH 8
+
+@interface AvdeviceAvfoundationDigest : NSObject
++ (NSString *)fromString:(NSString *)input;
+@end
+
+@implementation AvdeviceAvfoundationDigest : NSObject
++ (NSString *) fromString:(NSString *)input {
+    const char *cStr = [input UTF8String];
+    unsigned char digest[CC_SHA256_DIGEST_LENGTH];
+    CC_SHA256( cStr, strlen(cStr), digest );
+
+ NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
+
+    for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++)
+    [output appendFormat:@"%02x", digest[i]];
+
+ // The "d" prefix makes sure that digest strings are never mistaken for numbers. + return [@"d" stringByAppendingString:[output substringToIndex:DEVICES_DIGEST_LENGTH]];
+}
+@end
+
#define MAX_QUEUED_OBJECTS 10

@interface AvdeviceAvfoundationBuffer : NSObject
@@ -860,13 +883,15 @@ static int avf_read_header(AVFormatContext *s)
        av_log(ctx, AV_LOG_INFO, "AVFoundation video devices:\n");
        for (AVCaptureDevice *device in devices) {
            const char *name = [[device localizedName] UTF8String];
+ NSString *digest = [AvdeviceAvfoundationDigest fromString:[[NSString alloc] initWithUTF8String:name]];
            index            = [devices indexOfObject:device];
-            av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
+ av_log(ctx, AV_LOG_INFO, "[%d] %s (digest: %s)\n", index, name, [digest UTF8String]);
        }
        for (AVCaptureDevice *device in devices_muxed) {
            const char *name = [[device localizedName] UTF8String];
+ NSString *digest = [AvdeviceAvfoundationDigest fromString:[[NSString alloc] initWithUTF8String:name]]; index = [devices count] + [devices_muxed indexOfObject:device];
-            av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
+ av_log(ctx, AV_LOG_INFO, "[%d] %s (digest: %s)\n", index, name, [digest UTF8String]);
        }
#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
        if (num_screens > 0) {
@@ -882,8 +907,9 @@ static int avf_read_header(AVFormatContext *s)
devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
        for (AVCaptureDevice *device in devices) {
            const char *name = [[device localizedName] UTF8String];
+ NSString *digest = [AvdeviceAvfoundationDigest fromString:[[NSString alloc] initWithUTF8String:name]];
            int index  = [devices indexOfObject:device];
-            av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
+ av_log(ctx, AV_LOG_INFO, "[%d] %s (digest: %s)\n", index, name, [digest UTF8String]);
        }
         goto fail;
    }
@@ -945,14 +971,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;
+            }
+
+ NSString *digest = [AvdeviceAvfoundationDigest fromString:[[NSString alloc] initWithUTF8String:name]]; + if (!strncmp(ctx->video_filename, [digest UTF8String], 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;
+            }
+
+ NSString *digest = [AvdeviceAvfoundationDigest fromString:[[NSString alloc] initWithUTF8String:name]]; + if (!strncmp(ctx->video_filename, [digest UTF8String], strlen(ctx->video_filename))) {
                video_device = device;
                ctx->video_is_muxed = 1;
                break;
@@ -1017,7 +1058,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;
+            }
+
+ NSString *digest = [AvdeviceAvfoundationDigest fromString:[[NSString alloc] initWithUTF8String:name]]; + if (!strncmp(ctx->audio_filename, [digest UTF8String], strlen(ctx->audio_filename))) {
                audio_device = device;
                break;
            }
--
2.30.1 (Apple Git-130)

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@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-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to