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