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
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel