Creates a new device context from another of a different type which refers to the same underlying hardware.tags/n4.0
| @@ -13,6 +13,9 @@ libavutil: 2015-08-28 | |||
| API changes, most recent first: | |||
| 2017-03-xx - xxxxxxx - lavu 55.34.0 - hwcontext.h | |||
| Add av_hwdevice_ctx_create_derived(). | |||
| 2017-02-10 - xxxxxxx - lavu 55.33.0 - spherical.h | |||
| Add AV_SPHERICAL_EQUIRECTANGULAR_TILE, av_spherical_tile_bounds(), | |||
| and projection-specific properties (bound_left, bound_top, bound_right, | |||
| @@ -65,6 +65,8 @@ static void hwdevice_ctx_free(void *opaque, uint8_t *data) | |||
| if (ctx->free) | |||
| ctx->free(ctx); | |||
| av_buffer_unref(&ctx->internal->source_device); | |||
| av_freep(&ctx->hwctx); | |||
| av_freep(&ctx->internal->priv); | |||
| av_freep(&ctx->internal); | |||
| @@ -535,6 +537,69 @@ fail: | |||
| 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) | |||
| { | |||
| HWMapDescriptor *hwmap = (HWMapDescriptor*)data; | |||
| @@ -268,6 +268,32 @@ int av_hwdevice_ctx_init(AVBufferRef *ref); | |||
| int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type, | |||
| 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. | |||
| * | |||
| @@ -66,6 +66,8 @@ typedef struct HWContextType { | |||
| int (*device_create)(AVHWDeviceContext *ctx, const char *device, | |||
| AVDictionary *opts, int flags); | |||
| int (*device_derive)(AVHWDeviceContext *dst_ctx, | |||
| AVHWDeviceContext *src_ctx, int flags); | |||
| int (*device_init)(AVHWDeviceContext *ctx); | |||
| void (*device_uninit)(AVHWDeviceContext *ctx); | |||
| @@ -95,6 +97,12 @@ typedef struct HWContextType { | |||
| struct AVHWDeviceInternal { | |||
| const HWContextType *hw_type; | |||
| void *priv; | |||
| /** | |||
| * For a derived device, a reference to the original device | |||
| * context it was derived from. | |||
| */ | |||
| AVBufferRef *source_device; | |||
| }; | |||
| struct AVHWFramesInternal { | |||
| @@ -54,7 +54,7 @@ | |||
| */ | |||
| #define LIBAVUTIL_VERSION_MAJOR 55 | |||
| #define LIBAVUTIL_VERSION_MINOR 33 | |||
| #define LIBAVUTIL_VERSION_MINOR 34 | |||
| #define LIBAVUTIL_VERSION_MICRO 0 | |||
| #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | |||