On Sun, 19 Feb 2017 18:46:33 +0000
Mark Thompson <[email protected]> wrote:
> Also refactor a little and improve error messages to make failure
> cases easier to understand.
> ---
> libavfilter/vf_hwmap.c | 67
> +++++++++++++++++++++++++++++++++++++++-----------
> 1 file changed, 52 insertions(+), 15 deletions(-)
>
> diff --git a/libavfilter/vf_hwmap.c b/libavfilter/vf_hwmap.c
> index 11595bd6c..6e890dae3 100644
> --- a/libavfilter/vf_hwmap.c
> +++ b/libavfilter/vf_hwmap.c
> @@ -34,6 +34,7 @@ typedef struct HWMapContext {
> AVBufferRef *hwframes_ref;
>
> int mode;
> + char *derive_device_type;
> int map_backwards;
> } HWMapContext;
>
> @@ -52,6 +53,7 @@ static int hwmap_config_output(AVFilterLink *outlink)
> HWMapContext *ctx = avctx->priv;
> AVFilterLink *inlink = avctx->inputs[0];
> AVHWFramesContext *hwfc;
> + AVBufferRef *device;
> const AVPixFmtDescriptor *desc;
> int err;
>
> @@ -59,30 +61,61 @@ static int hwmap_config_output(AVFilterLink *outlink)
> av_get_pix_fmt_name(inlink->format),
> av_get_pix_fmt_name(outlink->format));
>
> + av_buffer_unref(&ctx->hwframes_ref);
> + av_buffer_unref(&ctx->hwdevice_ref);
> +
> + device = avctx->hw_device_ctx;
> +
> if (inlink->hw_frames_ctx) {
> hwfc = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
>
> + if (ctx->derive_device_type) {
> + enum AVHWDeviceType type;
> +
> + type = av_hwdevice_find_type_by_name(ctx->derive_device_type);
> + if (type == -1) {
> + av_log(avctx, AV_LOG_ERROR, "Invalid device type.\n");
> + goto fail;
> + }
> +
> + err = av_hwdevice_ctx_create_derived(&ctx->hwdevice_ref, type,
> + hwfc->device_ref, 0);
> + if (err < 0) {
> + av_log(avctx, AV_LOG_ERROR, "Failed to created derived "
> + "device context: %d.\n", err);
> + goto fail;
> + }
> +
> + device = ctx->hwdevice_ref;
> + }
> +
> desc = av_pix_fmt_desc_get(outlink->format);
> - if (!desc)
> - return AVERROR(EINVAL);
> + if (!desc) {
> + err = AVERROR(EINVAL);
> + goto fail;
> + }
>
> if (inlink->format == hwfc->format &&
> (desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
> // Map between two hardware formats (including the case of
> // undoing an existing mapping).
>
> - ctx->hwdevice_ref = av_buffer_ref(avctx->hw_device_ctx);
> - if (!ctx->hwdevice_ref) {
> - err = AVERROR(ENOMEM);
> + if (!device) {
> + av_log(avctx, AV_LOG_ERROR, "A device reference is "
> + "required to map to a hardware format.\n");
> + err = AVERROR(EINVAL);
> goto fail;
> }
>
> err = av_hwframe_ctx_create_derived(&ctx->hwframes_ref,
> outlink->format,
> - ctx->hwdevice_ref,
> + device,
> inlink->hw_frames_ctx, 0);
> - if (err < 0)
> + if (err < 0) {
> + av_log(avctx, AV_LOG_ERROR, "Failed to create derived "
> + "frames context: %d.\n", err);
> goto fail;
> + }
>
> } else if ((outlink->format == hwfc->format &&
> inlink->format == hwfc->sw_format) ||
> @@ -90,8 +123,6 @@ static int hwmap_config_output(AVFilterLink *outlink)
> // Map from a hardware format to a software format, or
> // undo an existing such mapping.
>
> - ctx->hwdevice_ref = NULL;
> -
> ctx->hwframes_ref = av_buffer_ref(inlink->hw_frames_ctx);
> if (!ctx->hwframes_ref) {
> err = AVERROR(ENOMEM);
> @@ -115,15 +146,17 @@ static int hwmap_config_output(AVFilterLink *outlink)
> // returns frames mapped from that to the previous link in
> // order to fill them without an additional copy.
>
> - ctx->map_backwards = 1;
> -
> - ctx->hwdevice_ref = av_buffer_ref(avctx->hw_device_ctx);
> - if (!ctx->hwdevice_ref) {
> - err = AVERROR(ENOMEM);
> + if (!device) {
> + av_log(avctx, AV_LOG_ERROR, "A device reference is "
> + "required to create new frames with backwards "
> + "mapping.\n");
> + err = AVERROR(EINVAL);
> goto fail;
> }
>
> - ctx->hwframes_ref = av_hwframe_ctx_alloc(ctx->hwdevice_ref);
> + ctx->map_backwards = 1;
> +
> + ctx->hwframes_ref = av_hwframe_ctx_alloc(device);
> if (!ctx->hwframes_ref) {
> err = AVERROR(ENOMEM);
> goto fail;
> @@ -293,6 +326,10 @@ static const AVOption hwmap_options[] = {
> 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWFRAME_MAP_DIRECT },
> INT_MIN, INT_MAX, FLAGS, "mode" },
>
> + { "derive_device", "Derive a new device of this type",
> + OFFSET(derive_device_type), AV_OPT_TYPE_STRING,
> + { .str = NULL }, 0, 0, FLAGS },
> +
> { NULL },
> };
>
Maybe I don't fully understand how this filter works, but doesn't it
already support derived frames contexts in git master? What's the
difference to derived device contexts?
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel