History

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.

Philip Langdale committed 7 years ago

Commit d7210ce1 parent d84a30e1 file · +43 −10Browse files

Unified · Split

libavutil/hwcontext.c+43−10
@@ -444,21 +444,54 @@ int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags) · 443 unmodified lines
444 if (!dst->buf[0])444 if (!dst->buf[0])
445 return transfer_data_alloc(dst, src, flags);445 return transfer_data_alloc(dst, src, flags);
446 446
447 if (src->hw_frames_ctx) {447 /*
448 ctx = (AVHWFramesContext*)src->hw_frames_ctx->data;448 * Hardware -> Hardware Transfer.
449 * Unlike Software -> Hardware or Hardware -> Software, the transfer
450 * function could be provided by either the src or dst, depending on
451 * the specific combination of hardware.
452 */
453 if (src->hw_frames_ctx && dst->hw_frames_ctx) {
454 AVHWFramesContext *src_ctx =
455 (AVHWFramesContext*)src->hw_frames_ctx->data;
456 AVHWFramesContext *dst_ctx =
457 (AVHWFramesContext*)dst->hw_frames_ctx->data;
458
459 if (src_ctx->internal->source_frames) {
460 av_log(src_ctx, AV_LOG_ERROR,
461 "A device with a derived frame context cannot be used as "
462 "the source of a HW -> HW transfer.");
463 return AVERROR(ENOSYS);
464 }
449 465
450 ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src);466 if (dst_ctx->internal->source_frames) {
451 if (ret < 0)467 av_log(src_ctx, AV_LOG_ERROR,
452 return ret;468 "A device with a derived frame context cannot be used as "
453 } else if (dst->hw_frames_ctx) {469 "the destination of a HW -> HW transfer.");
454 ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;470 return AVERROR(ENOSYS);
471 }
455 472
456 ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);473 ret = src_ctx->internal->hw_type->transfer_data_from(src_ctx, dst, src);
474 if (ret == AVERROR(ENOSYS))
475 ret = dst_ctx->internal->hw_type->transfer_data_to(dst_ctx, dst, src);
457 if (ret < 0)476 if (ret < 0)
458 return ret;477 return ret;
459 } else478 } else {
460 return AVERROR(ENOSYS);479 if (src->hw_frames_ctx) {
480 ctx = (AVHWFramesContext*)src->hw_frames_ctx->data;
481
482 ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src);
483 if (ret < 0)
484 return ret;
485 } else if (dst->hw_frames_ctx) {
486 ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
461 487
488 ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);
489 if (ret < 0)
490 return ret;
491 } else {
492 return AVERROR(ENOSYS);
493 }
494 }
462 return 0;495 return 0;
463}496}
464 497

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t