mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
lavu/hwcontext: clarify behavior on av_hwframe_map() failure
Clear anything that av_hwframe_map() might have done to the destination frame, but leave caller-provided fields unchanged.
This commit is contained in:
parent
6fc5e5a52c
commit
09ca2f1950
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "avassert.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "hwcontext.h"
|
#include "hwcontext.h"
|
||||||
@ -788,6 +789,8 @@ fail:
|
|||||||
|
|
||||||
int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
|
int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
|
||||||
{
|
{
|
||||||
|
AVBufferRef *orig_dst_frames = dst->hw_frames_ctx;
|
||||||
|
enum AVPixelFormat orig_dst_fmt = dst->format;
|
||||||
AVHWFramesContext *src_frames, *dst_frames;
|
AVHWFramesContext *src_frames, *dst_frames;
|
||||||
HWMapDescriptor *hwmap;
|
HWMapDescriptor *hwmap;
|
||||||
int ret;
|
int ret;
|
||||||
@ -824,8 +827,10 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
|
|||||||
src_frames->internal->hw_type->map_from) {
|
src_frames->internal->hw_type->map_from) {
|
||||||
ret = src_frames->internal->hw_type->map_from(src_frames,
|
ret = src_frames->internal->hw_type->map_from(src_frames,
|
||||||
dst, src, flags);
|
dst, src, flags);
|
||||||
if (ret != AVERROR(ENOSYS))
|
if (ret >= 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
else if (ret != AVERROR(ENOSYS))
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,12 +841,30 @@ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
|
|||||||
dst_frames->internal->hw_type->map_to) {
|
dst_frames->internal->hw_type->map_to) {
|
||||||
ret = dst_frames->internal->hw_type->map_to(dst_frames,
|
ret = dst_frames->internal->hw_type->map_to(dst_frames,
|
||||||
dst, src, flags);
|
dst, src, flags);
|
||||||
if (ret != AVERROR(ENOSYS))
|
if (ret >= 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
else if (ret != AVERROR(ENOSYS))
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AVERROR(ENOSYS);
|
return AVERROR(ENOSYS);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
// if the caller provided dst frames context, it should be preserved
|
||||||
|
// by this function
|
||||||
|
av_assert0(orig_dst_frames == NULL ||
|
||||||
|
orig_dst_frames == dst->hw_frames_ctx);
|
||||||
|
|
||||||
|
// preserve user-provided dst frame fields, but clean
|
||||||
|
// anything we might have set
|
||||||
|
dst->hw_frames_ctx = NULL;
|
||||||
|
av_frame_unref(dst);
|
||||||
|
|
||||||
|
dst->hw_frames_ctx = orig_dst_frames;
|
||||||
|
dst->format = orig_dst_fmt;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
|
int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
|
||||||
|
@ -571,6 +571,10 @@ enum {
|
|||||||
* possible with the given arguments and hwframe setup, while other return
|
* possible with the given arguments and hwframe setup, while other return
|
||||||
* values indicate that it failed somehow.
|
* values indicate that it failed somehow.
|
||||||
*
|
*
|
||||||
|
* On failure, the destination frame will be left blank, except for the
|
||||||
|
* hw_frames_ctx/format fields thay may have been set by the caller - those will
|
||||||
|
* be preserved as they were.
|
||||||
|
*
|
||||||
* @param dst Destination frame, to contain the mapping.
|
* @param dst Destination frame, to contain the mapping.
|
||||||
* @param src Source frame, to be mapped.
|
* @param src Source frame, to be mapped.
|
||||||
* @param flags Some combination of AV_HWFRAME_MAP_* flags.
|
* @param flags Some combination of AV_HWFRAME_MAP_* flags.
|
||||||
|
Loading…
Reference in New Issue
Block a user