ffmpeg | branch: master | Philip Langdale <phil...@overt.org> | Wed Oct 23 18:01:52 2019 -0700| [d7210ce7f5418508d6f8eec6e90d978e06a2d49e] | committer: Lynne
lavu/hwcontext: Add support for HW -> HW transfers We are beginning to consider scenarios where a given HW Context may be able to transfer frames to another HW Context without passing via system memory - this would usually be when two contexts represent different APIs on the same device (eg: Vulkan and CUDA). This is modelled as a transfer, as we have today, but where both the src and the dst are hardware frames with hw contexts. We need to be careful to ensure the contexts are compatible - particularly, we cannot do transfers where one of the frames has been mapped via a derived frames context - we can only do transfers for frames that were directly allocated by the specified context. Additionally, as we have two hardware contexts, the transfer function could be implemented by either (or indeed both). To handle this uncertainty, we explicitly look for ENOSYS as an indicator to try the transfer in the other direction before giving up. > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d7210ce7f5418508d6f8eec6e90d978e06a2d49e --- libavutil/hwcontext.c | 53 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c index f1e404ab20..3189391c07 100644 --- a/libavutil/hwcontext.c +++ b/libavutil/hwcontext.c @@ -444,21 +444,54 @@ int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags) if (!dst->buf[0]) return transfer_data_alloc(dst, src, flags); - if (src->hw_frames_ctx) { - ctx = (AVHWFramesContext*)src->hw_frames_ctx->data; + /* + * Hardware -> Hardware Transfer. + * Unlike Software -> Hardware or Hardware -> Software, the transfer + * function could be provided by either the src or dst, depending on + * the specific combination of hardware. + */ + if (src->hw_frames_ctx && dst->hw_frames_ctx) { + AVHWFramesContext *src_ctx = + (AVHWFramesContext*)src->hw_frames_ctx->data; + AVHWFramesContext *dst_ctx = + (AVHWFramesContext*)dst->hw_frames_ctx->data; + + if (src_ctx->internal->source_frames) { + av_log(src_ctx, AV_LOG_ERROR, + "A device with a derived frame context cannot be used as " + "the source of a HW -> HW transfer."); + return AVERROR(ENOSYS); + } - ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src); - if (ret < 0) - return ret; - } else if (dst->hw_frames_ctx) { - ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data; + if (dst_ctx->internal->source_frames) { + av_log(src_ctx, AV_LOG_ERROR, + "A device with a derived frame context cannot be used as " + "the destination of a HW -> HW transfer."); + return AVERROR(ENOSYS); + } - ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src); + ret = src_ctx->internal->hw_type->transfer_data_from(src_ctx, dst, src); + if (ret == AVERROR(ENOSYS)) + ret = dst_ctx->internal->hw_type->transfer_data_to(dst_ctx, dst, src); if (ret < 0) return ret; - } else - return AVERROR(ENOSYS); + } else { + if (src->hw_frames_ctx) { + ctx = (AVHWFramesContext*)src->hw_frames_ctx->data; + + ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src); + if (ret < 0) + return ret; + } else if (dst->hw_frames_ctx) { + ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data; + ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src); + if (ret < 0) + return ret; + } else { + return AVERROR(ENOSYS); + } + } return 0; } _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".