|
|
|
@@ -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; |
|
|
|
} |
|
|
|
|
|
|
|
|