Quoting Mark Thompson (2017-03-05 00:57:30)
> Not yet enabled for any hwaccels.
> ---
>  avtools/Makefile     |   3 +-
>  avtools/avconv.c     |  22 +++
>  avtools/avconv.h     |  17 +++
>  avtools/avconv_hw.c  | 386 
> +++++++++++++++++++++++++++++++++++++++++++++++++++
>  avtools/avconv_opt.c |  33 ++++-
>  5 files changed, 455 insertions(+), 6 deletions(-)
>  create mode 100644 avtools/avconv_hw.c
> 

Is there going to be documentation at some point?

> +static enum AVHWDeviceType hw_device_match_type_in_name(const char 
> *codec_name)
> +{
> +    const char *type_name;
> +    enum AVHWDeviceType type;
> +    for (type = 0;; type++) {
> +        if (type == AV_HWDEVICE_TYPE_NONE)
> +            continue;

Should this use av_hwdevice_iterate_types()?

> +        type_name = av_hwdevice_get_type_name(type);
> +        if (!type_name)
> +            break;
> +        if (strstr(codec_name, type_name))
> +            return type;
> +    }
> +    return AV_HWDEVICE_TYPE_NONE;
> +}
> +
> +int hw_device_setup_for_decode(InputStream *ist)
> +{
> +    enum AVHWDeviceType type;
> +    HWDevice *dev;
> +    const char *type_name;
> +    int err;
> +
> +    if (ist->hwaccel_device) {
> +        dev = hw_device_get_by_name(ist->hwaccel_device);
> +        if (!dev) {
> +            char *tmp;
> +            size_t len;
> +            type = hw_device_match_type_by_hwaccel(ist->hwaccel_id);
> +            if (type == AV_HWDEVICE_TYPE_NONE) {
> +                // No match - this isn't necessarily invalid, though,
> +                // because an explicit device might not be needed or
> +                // the hwaccel setup could be handled elsewhere.
> +                return 0;
> +            }
> +            type_name = av_hwdevice_get_type_name(type);
> +            len = strlen(type_name) + 1 +
> +                  strlen(ist->hwaccel_device) + 1;
> +            tmp = av_malloc(len);
> +            if (!tmp)
> +                return AVERROR(ENOMEM);
> +            snprintf(tmp, len, "%s:%s", type_name, ist->hwaccel_device);
> +            err = hw_device_init_from_string(tmp, &dev);
> +            av_free(tmp);
> +            if (err < 0)
> +                return err;
> +        }
> +    } else {
> +        if (ist->hwaccel_id != HWACCEL_NONE)
> +            type = hw_device_match_type_by_hwaccel(ist->hwaccel_id);
> +        else
> +            type = hw_device_match_type_in_name(ist->dec->name);
> +        if (type != AV_HWDEVICE_TYPE_NONE) {
> +            dev = hw_device_get_by_type(type);
> +        } else {
> +            // No device required.
> +            return 0;
> +        }
> +    }
> +
> +    if (!dev) {
> +        av_log(ist->dec_ctx, AV_LOG_WARNING, "No device available "
> +               "for decoder (device type %s for codec %s).\n",
> +               av_hwdevice_get_type_name(type), ist->dec->name);
> +        return 0;
> +    }
> +
> +    ist->dec_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
> +    if (!ist->dec_ctx->hw_device_ctx)
> +        return AVERROR(ENOMEM);
> +
> +    return 0;
> +}
> +
> +int hw_device_setup_for_encode(OutputStream *ost)
> +{
> +    enum AVHWDeviceType type;
> +    HWDevice *dev;
> +
> +    type = hw_device_match_type_in_name(ost->enc->name);
> +    if (type != AV_HWDEVICE_TYPE_NONE) {
> +        dev = hw_device_get_by_type(type);
> +        if (!dev) {
> +            av_log(ost->enc_ctx, AV_LOG_WARNING, "No device available "
> +                   "for encoder (device type %s for codec %s).\n",
> +                   av_hwdevice_get_type_name(type), ost->enc->name);
> +            return 0;
> +        }
> +        ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
> +        if (!ost->enc_ctx->hw_device_ctx)
> +            return AVERROR(ENOMEM);
> +        return 0;
> +    } else {
> +        // No device required.
> +        return 0;
> +    }
> +}
> +
> +static int hwaccel_retrieve_data(AVCodecContext *avctx, AVFrame *input)
> +{
> +    InputStream *ist = avctx->opaque;
> +    AVFrame *output = 0;

NULL

> +    enum AVPixelFormat output_format = ist->hwaccel_output_format;
> +    int err;
> +
> +    if (input->format == output_format) {
> +        // Nothing to do.
> +        return 0;
> +    }
> +
> +    output = av_frame_alloc();
> +    if (!output)
> +        return AVERROR(ENOMEM);
> +
> +    output->format = output_format;
> +
> +    err = av_hwframe_transfer_data(output, input, 0);
> +    if (err < 0) {
> +        av_log(avctx, AV_LOG_ERROR, "Failed to transfer data to "
> +               "output frame: %d.\n", err);
> +        goto fail;
> +    }
> +
> +    err = av_frame_copy_props(output, input);
> +    if (err < 0) {
> +        av_frame_unref(output);
> +        goto fail;
> +    }
> +
> +    av_frame_unref(input);
> +    av_frame_move_ref(input, output);
> +    av_frame_free(&output);
> +
> +    return 0;
> +
> +fail:
> +    if (output)

Unnecessary, av_frame_free() is a no-op for NULL.

Generally looks good.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to