int hw_device_init_from_string(const char *arg, HWDevice **dev_out)

{

    // "type=name:device,key=value,key2=value2"

    // "type:device,key=value,key2=value2"

    // -> av_hwdevice_ctx_create()

    // "type=name@name"

    // "type@name"

    // -> av_hwdevice_ctx_create_derived()



    AVDictionary *options = NULL;

    char *type_name = NULL, *name = NULL, *device = NULL;

    enum AVHWDeviceType type;

    HWDevice *dev, *src;

    AVBufferRef *device_ref = NULL;

    int err;

    const char *errmsg, *p, *q;

    size_t k;



    k = strcspn(arg, ":=@");

    p = arg + k;



    type_name = av_strndup(arg, k);

    if (!type_name) {

        err = AVERROR(ENOMEM);

        goto fail;

    }

    type = av_hwdevice_find_type_by_name(type_name);

    if (type == AV_HWDEVICE_TYPE_NONE) {

        errmsg = "unknown device type";

        goto invalid;

    }



    if (*p == '=') {

        k = strcspn(p + 1, ":@");



        name = av_strndup(p + 1, k);

        if (!name) {

            err = AVERROR(ENOMEM);

            goto fail;

        }

        if (hw_device_get_by_name(name)) {

            errmsg = "named device already exists";

            goto invalid;

        }



        p += 1 + k;

    } else {

        // Give the device an automatic name of the form "type%d".

        // We arbitrarily limit at 1000 anonymous devices of the same

        // type - there is probably something else very wrong if you

        // get to this limit.

        size_t index_pos;

        int index, index_limit = 1000;

        index_pos = strlen(type_name);

        name = av_malloc(index_pos + 4);

        if (!name) {

            err = AVERROR(ENOMEM);

            goto fail;

        }

        for (index = 0; index < index_limit; index++) {

            snprintf(name, index_pos + 4, "%s%d", type_name, index);

            if (!hw_device_get_by_name(name))

                break;

        }

        if (index >= index_limit) {

            errmsg = "too many devices";

            goto invalid;

        }

    }



    if (!*p) {

        // New device with no parameters.

        err = av_hwdevice_ctx_create(&device_ref, type,

                                     NULL, NULL, 0);

        if (err < 0)

            goto fail;



    } else if (*p == ':') {

        // New device with some parameters.

        ++p;

        q = strchr(p, ',');

        if (q) {

            device = av_strndup(p, q - p);

            if (!device) {

                err = AVERROR(ENOMEM);

                goto fail;

            }

            err = av_dict_parse_string(&options, q + 1, "=", ",", 0);

            if (err < 0) {

                errmsg = "failed to parse options";

                goto invalid;

            }

        }



        err = av_hwdevice_ctx_create(&device_ref, type,

                                     device ? device : p, options, 0);

        if (err < 0)

            goto fail;



    } else if (*p == '@') {

        // Derive from existing device.



        src = hw_device_get_by_name(p + 1);

        if (!src) {

            errmsg = "invalid source device name";

            goto invalid;

        }



        err = av_hwdevice_ctx_create_derived(&device_ref, type,

                                             src->device_ref, 0);

        if (err < 0)

            goto fail;

    } else {

        errmsg = "parse error";

        goto invalid;

    }



    dev = hw_device_add();

    if (!dev) {

        err = AVERROR(ENOMEM);

        goto fail;

    }



    dev->name = name;

    dev->type = type;

    dev->device_ref = device_ref;



    if (dev_out)

        *dev_out = dev;



    name = NULL;

    err = 0;

done:

    av_freep(&type_name);

    av_freep(&name);

    av_freep(&device);

    av_dict_free(&options);

    return err;

invalid:

    av_log(NULL, AV_LOG_ERROR,

           "Invalid device specification \"%s\": %s\n", arg, errmsg);

    err = AVERROR(EINVAL);

    goto done;

fail:

    av_log(NULL, AV_LOG_ERROR,

           "Device creation failed: %d.\n", err);

    av_buffer_unref(&device_ref);

    goto done;

}

int hw_device_init_from_string(const char *arg, HWDevice **dev_out)

{

    

    

    

    

    

    



    AVDictionary *options = NULL;

    char *type_name = NULL, *name = NULL, *device = NULL;

    enum AVHWDeviceType type;

    HWDevice *dev, *src;

    AVBufferRef *device_ref = NULL;

    int err;

    const char *errmsg, *p, *q;

    size_t k;



    k = strcspn(arg, ":=@");

    p = arg + k;



    type_name = av_strndup(arg, k);

    if (!type_name) {

        err = AVERROR(ENOMEM);

        goto fail;

    }

    type = av_hwdevice_find_type_by_name(type_name);

    if (type == AV_HWDEVICE_TYPE_NONE) {

        errmsg = "unknown device type";

        goto invalid;

    }



    if (*p == '=') {

        k = strcspn(p + 1, ":@");



        name = av_strndup(p + 1, k);

        if (!name) {

            err = AVERROR(ENOMEM);

            goto fail;

        }

        if (hw_device_get_by_name(name)) {

            errmsg = "named device already exists";

            goto invalid;

        }



        p += 1 + k;

    } else {

        

        

        

        

        size_t index_pos;

        int index, index_limit = 1000;

        index_pos = strlen(type_name);

        name = av_malloc(index_pos + 4);

        if (!name) {

            err = AVERROR(ENOMEM);

            goto fail;

        }

        for (index = 0; index < index_limit; index++) {

            snprintf(name, index_pos + 4, "%s%d", type_name, index);

            if (!hw_device_get_by_name(name))

                break;

        }

        if (index >= index_limit) {

            errmsg = "too many devices";

            goto invalid;

        }

    }



    if (!*p) {

        

        err = av_hwdevice_ctx_create(&device_ref, type,

                                     NULL, NULL, 0);

        if (err < 0)

            goto fail;



    } else if (*p == ':') {

        

        ++p;

        q = strchr(p, ',');

        if (q) {

            device = av_strndup(p, q - p);

            if (!device) {

                err = AVERROR(ENOMEM);

                goto fail;

            }

            err = av_dict_parse_string(&options, q + 1, "=", ",", 0);

            if (err < 0) {

                errmsg = "failed to parse options";

                goto invalid;

            }

        }



        err = av_hwdevice_ctx_create(&device_ref, type,

                                     device ? device : p, options, 0);

        if (err < 0)

            goto fail;



    } else if (*p == '@') {

        



        src = hw_device_get_by_name(p + 1);

        if (!src) {

            errmsg = "invalid source device name";

            goto invalid;

        }



        err = av_hwdevice_ctx_create_derived(&device_ref, type,

                                             src->device_ref, 0);

        if (err < 0)

            goto fail;

    } else {

        errmsg = "parse error";

        goto invalid;

    }



    dev = hw_device_add();

    if (!dev) {

        err = AVERROR(ENOMEM);

        goto fail;

    }



    dev->name = name;

    dev->type = type;

    dev->device_ref = device_ref;



    if (dev_out)

        *dev_out = dev;



    name = NULL;

    err = 0;

done:

    av_freep(&type_name);

    av_freep(&name);

    av_freep(&device);

    av_dict_free(&options);

    return err;

invalid:

    av_log(NULL, AV_LOG_ERROR,

           "Invalid device specification \"%s\": %s\n", arg, errmsg);

    err = AVERROR(EINVAL);

    goto done;

fail:

    av_log(NULL, AV_LOG_ERROR,

           "Device creation failed: %d.\n", err);

    av_buffer_unref(&device_ref);

    goto done;

}

int FUNC_0(const char *VAR_0, HWDevice **VAR_1)

{

    

    

    

    

    

    



    AVDictionary *options = NULL;

    char *VAR_2 = NULL, *VAR_3 = NULL, *VAR_4 = NULL;

    enum AVHWDeviceType VAR_5;

    HWDevice *dev, *src;

    AVBufferRef *device_ref = NULL;

    int VAR_6;

    const char *VAR_7, *VAR_8, *VAR_9;

    size_t k;



    k = strcspn(VAR_0, ":=@");

    VAR_8 = VAR_0 + k;



    VAR_2 = av_strndup(VAR_0, k);

    if (!VAR_2) {

        VAR_6 = AVERROR(ENOMEM);

        goto fail;

    }

    VAR_5 = av_hwdevice_find_type_by_name(VAR_2);

    if (VAR_5 == AV_HWDEVICE_TYPE_NONE) {

        VAR_7 = "unknown VAR_4 VAR_5";

        goto invalid;

    }



    if (*VAR_8 == '=') {

        k = strcspn(VAR_8 + 1, ":@");



        VAR_3 = av_strndup(VAR_8 + 1, k);

        if (!VAR_3) {

            VAR_6 = AVERROR(ENOMEM);

            goto fail;

        }

        if (hw_device_get_by_name(VAR_3)) {

            VAR_7 = "named VAR_4 already exists";

            goto invalid;

        }



        VAR_8 += 1 + k;

    } else {

        

        

        

        

        size_t index_pos;

        int VAR_10, VAR_11 = 1000;

        index_pos = strlen(VAR_2);

        VAR_3 = av_malloc(index_pos + 4);

        if (!VAR_3) {

            VAR_6 = AVERROR(ENOMEM);

            goto fail;

        }

        for (VAR_10 = 0; VAR_10 < VAR_11; VAR_10++) {

            snprintf(VAR_3, index_pos + 4, "%s%d", VAR_2, VAR_10);

            if (!hw_device_get_by_name(VAR_3))

                break;

        }

        if (VAR_10 >= VAR_11) {

            VAR_7 = "too many devices";

            goto invalid;

        }

    }



    if (!*VAR_8) {

        

        VAR_6 = av_hwdevice_ctx_create(&device_ref, VAR_5,

                                     NULL, NULL, 0);

        if (VAR_6 < 0)

            goto fail;



    } else if (*VAR_8 == ':') {

        

        ++VAR_8;

        VAR_9 = strchr(VAR_8, ',');

        if (VAR_9) {

            VAR_4 = av_strndup(VAR_8, VAR_9 - VAR_8);

            if (!VAR_4) {

                VAR_6 = AVERROR(ENOMEM);

                goto fail;

            }

            VAR_6 = av_dict_parse_string(&options, VAR_9 + 1, "=", ",", 0);

            if (VAR_6 < 0) {

                VAR_7 = "failed to parse options";

                goto invalid;

            }

        }



        VAR_6 = av_hwdevice_ctx_create(&device_ref, VAR_5,

                                     VAR_4 ? VAR_4 : VAR_8, options, 0);

        if (VAR_6 < 0)

            goto fail;



    } else if (*VAR_8 == '@') {

        



        src = hw_device_get_by_name(VAR_8 + 1);

        if (!src) {

            VAR_7 = "invalid source VAR_4 VAR_3";

            goto invalid;

        }



        VAR_6 = av_hwdevice_ctx_create_derived(&device_ref, VAR_5,

                                             src->device_ref, 0);

        if (VAR_6 < 0)

            goto fail;

    } else {

        VAR_7 = "parse error";

        goto invalid;

    }



    dev = hw_device_add();

    if (!dev) {

        VAR_6 = AVERROR(ENOMEM);

        goto fail;

    }



    dev->VAR_3 = VAR_3;

    dev->VAR_5 = VAR_5;

    dev->device_ref = device_ref;



    if (VAR_1)

        *VAR_1 = dev;



    VAR_3 = NULL;

    VAR_6 = 0;

done:

    av_freep(&VAR_2);

    av_freep(&VAR_3);

    av_freep(&VAR_4);

    av_dict_free(&options);

    return VAR_6;

invalid:

    av_log(NULL, AV_LOG_ERROR,

           "Invalid VAR_4 specification \"%s\": %s\n", VAR_0, VAR_7);

    VAR_6 = AVERROR(EINVAL);

    goto done;

fail:

    av_log(NULL, AV_LOG_ERROR,

           "Device creation failed: %d.\n", VAR_6);

    av_buffer_unref(&device_ref);

    goto done;

}

int FUNC_0(const char *VAR_0, HWDevice **VAR_1)
{ AVDictionary *options = NULL; char *VAR_2 = NULL, *VAR_3 = NULL, *VAR_4 = NULL; enum AVHWDeviceType VAR_5; HWDevice *dev, *src; AVBufferRef *device_ref = NULL; int VAR_6; const char *VAR_7, *VAR_8, *VAR_9; size_t k; k = strcspn(VAR_0, ":=@"); VAR_8 = VAR_0 + k; VAR_2 = av_strndup(VAR_0, k); if (!VAR_2) { VAR_6 = AVERROR(ENOMEM); goto fail; } VAR_5 = av_hwdevice_find_type_by_name(VAR_2); if (VAR_5 == AV_HWDEVICE_TYPE_NONE) { VAR_7 = "unknown VAR_4 VAR_5"; goto invalid; } if (*VAR_8 == '=') { k = strcspn(VAR_8 + 1, ":@"); VAR_3 = av_strndup(VAR_8 + 1, k); if (!VAR_3) { VAR_6 = AVERROR(ENOMEM); goto fail; } if (hw_device_get_by_name(VAR_3)) { VAR_7 = "named VAR_4 already exists"; goto invalid; } VAR_8 += 1 + k; } else { size_t index_pos; int VAR_10, VAR_11 = 1000; index_pos = strlen(VAR_2); VAR_3 = av_malloc(index_pos + 4); if (!VAR_3) { VAR_6 = AVERROR(ENOMEM); goto fail; } for (VAR_10 = 0; VAR_10 < VAR_11; VAR_10++) { snprintf(VAR_3, index_pos + 4, "%s%d", VAR_2, VAR_10); if (!hw_device_get_by_name(VAR_3))
break; } if (VAR_10 >= VAR_11) { VAR_7 = "too many devices"; goto invalid; } } if (!*VAR_8) { VAR_6 = av_hwdevice_ctx_create(&device_ref, VAR_5,
NULL, NULL, 0); if (VAR_6 < 0)
goto fail; } else if (*VAR_8 == ':') { ++VAR_8; VAR_9 = strchr(VAR_8, ','); if (VAR_9) { VAR_4 = av_strndup(VAR_8, VAR_9 - VAR_8); if (!VAR_4) { VAR_6 = AVERROR(ENOMEM); goto fail; } VAR_6 = av_dict_parse_string(&options, VAR_9 + 1, "=", ",", 0); if (VAR_6 < 0) { VAR_7 = "failed to parse options"; goto invalid; } } VAR_6 = av_hwdevice_ctx_create(&device_ref, VAR_5,
VAR_4 ? VAR_4 : VAR_8, options, 0); if (VAR_6 < 0)
goto fail; } else if (*VAR_8 == '@') { src = hw_device_get_by_name(VAR_8 + 1); if (!src) { VAR_7 = "invalid source VAR_4 VAR_3"; goto invalid; } VAR_6 = av_hwdevice_ctx_create_derived(&device_ref, VAR_5,
src->device_ref, 0); if (VAR_6 < 0)
goto fail; } else { VAR_7 = "parse error"; goto invalid; } dev = hw_device_add(); if (!dev) { VAR_6 = AVERROR(ENOMEM); goto fail; } dev->VAR_3 = VAR_3; dev->VAR_5 = VAR_5; dev->device_ref = device_ref; if (VAR_1)
*VAR_1 = dev; VAR_3 = NULL; VAR_6 = 0; done:
av_freep(&VAR_2); av_freep(&VAR_3); av_freep(&VAR_4); av_dict_free(&options); return VAR_6; invalid:
av_log(NULL, AV_LOG_ERROR,
"Invalid VAR_4 specification \"%s\": %s\n", VAR_0, VAR_7); VAR_6 = AVERROR(EINVAL); goto done; fail:
av_log(NULL, AV_LOG_ERROR,
"Device creation failed: %d.\n", VAR_6); av_buffer_unref(&device_ref); goto done; }