On 20/02/17 06:16, wm4 wrote:
> 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?

It already supports derived frames contexts, but only to the single filter 
device (hw_device_ctx, or now -filter_hw_device).  Deriving devices inside 
hwmap allows us to more magical things without having to make all the devices 
at the top level and pass them into lavfi.  (Yes, I am using this to duck the 
multiple-devices-in-lavfi problem.  I am not ashamed.)
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to