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

Reply via email to