hwcontext: Add device derivation
Creates a new device context from another of a different type which refers to the same underlying hardware. (cherry picked from commit b266ad56fe0e4ce5bb70118ba2e2b1dabfaf76ce)
This commit is contained in:
parent
92bd089745
commit
b22172f6f3
@ -15,6 +15,9 @@ libavutil: 2015-08-28
|
|||||||
|
|
||||||
API changes, most recent first:
|
API changes, most recent first:
|
||||||
|
|
||||||
|
2017-06-14 - xxxxxxx - lavu 55.64.100 - hwcontext.h
|
||||||
|
Add av_hwdevice_ctx_create_derived().
|
||||||
|
|
||||||
2017-05-15 - xxxxxxxxxx - lavc 57.96.100 - avcodec.h
|
2017-05-15 - xxxxxxxxxx - lavc 57.96.100 - avcodec.h
|
||||||
VideoToolbox hardware-accelerated decoding now supports the new hwaccel API,
|
VideoToolbox hardware-accelerated decoding now supports the new hwaccel API,
|
||||||
which can create the decoder context and allocate hardware frames automatically.
|
which can create the decoder context and allocate hardware frames automatically.
|
||||||
|
@ -68,6 +68,8 @@ static void hwdevice_ctx_free(void *opaque, uint8_t *data)
|
|||||||
if (ctx->free)
|
if (ctx->free)
|
||||||
ctx->free(ctx);
|
ctx->free(ctx);
|
||||||
|
|
||||||
|
av_buffer_unref(&ctx->internal->source_device);
|
||||||
|
|
||||||
av_freep(&ctx->hwctx);
|
av_freep(&ctx->hwctx);
|
||||||
av_freep(&ctx->internal->priv);
|
av_freep(&ctx->internal->priv);
|
||||||
av_freep(&ctx->internal);
|
av_freep(&ctx->internal);
|
||||||
@ -538,6 +540,69 @@ fail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr,
|
||||||
|
enum AVHWDeviceType type,
|
||||||
|
AVBufferRef *src_ref, int flags)
|
||||||
|
{
|
||||||
|
AVBufferRef *dst_ref = NULL, *tmp_ref;
|
||||||
|
AVHWDeviceContext *dst_ctx, *tmp_ctx;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
tmp_ref = src_ref;
|
||||||
|
while (tmp_ref) {
|
||||||
|
tmp_ctx = (AVHWDeviceContext*)tmp_ref->data;
|
||||||
|
if (tmp_ctx->type == type) {
|
||||||
|
dst_ref = av_buffer_ref(tmp_ref);
|
||||||
|
if (!dst_ref) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
tmp_ref = tmp_ctx->internal->source_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst_ref = av_hwdevice_ctx_alloc(type);
|
||||||
|
if (!dst_ref) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
dst_ctx = (AVHWDeviceContext*)dst_ref->data;
|
||||||
|
|
||||||
|
tmp_ref = src_ref;
|
||||||
|
while (tmp_ref) {
|
||||||
|
tmp_ctx = (AVHWDeviceContext*)tmp_ref->data;
|
||||||
|
if (dst_ctx->internal->hw_type->device_derive) {
|
||||||
|
ret = dst_ctx->internal->hw_type->device_derive(dst_ctx,
|
||||||
|
tmp_ctx,
|
||||||
|
flags);
|
||||||
|
if (ret == 0) {
|
||||||
|
dst_ctx->internal->source_device = av_buffer_ref(src_ref);
|
||||||
|
if (!dst_ctx->internal->source_device) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (ret != AVERROR(ENOSYS))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
tmp_ref = tmp_ctx->internal->source_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = AVERROR(ENOSYS);
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
done:
|
||||||
|
*dst_ref_ptr = dst_ref;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
av_buffer_unref(&dst_ref);
|
||||||
|
*dst_ref_ptr = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void ff_hwframe_unmap(void *opaque, uint8_t *data)
|
static void ff_hwframe_unmap(void *opaque, uint8_t *data)
|
||||||
{
|
{
|
||||||
HWMapDescriptor *hwmap = (HWMapDescriptor*)data;
|
HWMapDescriptor *hwmap = (HWMapDescriptor*)data;
|
||||||
|
@ -270,6 +270,32 @@ int av_hwdevice_ctx_init(AVBufferRef *ref);
|
|||||||
int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type,
|
int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type,
|
||||||
const char *device, AVDictionary *opts, int flags);
|
const char *device, AVDictionary *opts, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new device of the specified type from an existing device.
|
||||||
|
*
|
||||||
|
* If the source device is a device of the target type or was originally
|
||||||
|
* derived from such a device (possibly through one or more intermediate
|
||||||
|
* devices of other types), then this will return a reference to the
|
||||||
|
* existing device of the same type as is requested.
|
||||||
|
*
|
||||||
|
* Otherwise, it will attempt to derive a new device from the given source
|
||||||
|
* device. If direct derivation to the new type is not implemented, it will
|
||||||
|
* attempt the same derivation from each ancestor of the source device in
|
||||||
|
* turn looking for an implemented derivation method.
|
||||||
|
*
|
||||||
|
* @param dst_ctx On success, a reference to the newly-created
|
||||||
|
* AVHWDeviceContext.
|
||||||
|
* @param type The type of the new device to create.
|
||||||
|
* @param src_ctx A reference to an existing AVHWDeviceContext which will be
|
||||||
|
* used to create the new device.
|
||||||
|
* @param flags Currently unused; should be set to zero.
|
||||||
|
* @return Zero on success, a negative AVERROR code on failure.
|
||||||
|
*/
|
||||||
|
int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ctx,
|
||||||
|
enum AVHWDeviceType type,
|
||||||
|
AVBufferRef *src_ctx, int flags);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate an AVHWFramesContext tied to a given device context.
|
* Allocate an AVHWFramesContext tied to a given device context.
|
||||||
*
|
*
|
||||||
|
@ -66,6 +66,8 @@ typedef struct HWContextType {
|
|||||||
|
|
||||||
int (*device_create)(AVHWDeviceContext *ctx, const char *device,
|
int (*device_create)(AVHWDeviceContext *ctx, const char *device,
|
||||||
AVDictionary *opts, int flags);
|
AVDictionary *opts, int flags);
|
||||||
|
int (*device_derive)(AVHWDeviceContext *dst_ctx,
|
||||||
|
AVHWDeviceContext *src_ctx, int flags);
|
||||||
|
|
||||||
int (*device_init)(AVHWDeviceContext *ctx);
|
int (*device_init)(AVHWDeviceContext *ctx);
|
||||||
void (*device_uninit)(AVHWDeviceContext *ctx);
|
void (*device_uninit)(AVHWDeviceContext *ctx);
|
||||||
@ -95,6 +97,12 @@ typedef struct HWContextType {
|
|||||||
struct AVHWDeviceInternal {
|
struct AVHWDeviceInternal {
|
||||||
const HWContextType *hw_type;
|
const HWContextType *hw_type;
|
||||||
void *priv;
|
void *priv;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a derived device, a reference to the original device
|
||||||
|
* context it was derived from.
|
||||||
|
*/
|
||||||
|
AVBufferRef *source_device;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AVHWFramesInternal {
|
struct AVHWFramesInternal {
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define LIBAVUTIL_VERSION_MAJOR 55
|
#define LIBAVUTIL_VERSION_MAJOR 55
|
||||||
#define LIBAVUTIL_VERSION_MINOR 63
|
#define LIBAVUTIL_VERSION_MINOR 64
|
||||||
#define LIBAVUTIL_VERSION_MICRO 100
|
#define LIBAVUTIL_VERSION_MICRO 100
|
||||||
|
|
||||||
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
|
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user