[FFmpeg-devel] [PATCH v2 03/03] libavdevice/avfoundation.m: Allow to select devices by digest.

Marvin Scholz epirat07 at gmail.com
Mon Dec 13 20:25:16 EET 2021


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 <toots at 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
> +
> + at interface AvdeviceAvfoundationDigest : NSObject
> ++ (NSString *)fromString:(NSString *)input;
> + at end
> +
> + at 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]];
> +}
> + at 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 at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".


More information about the ffmpeg-devel mailing list