Creates a new device context from another of a different type which refers to the same underlying hardware.
Unified · Split
| @@ -13,6 +13,9 @@ libavutil: 2015-08-28 · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | API changes, most recent first: |
| 15 | 15 | |
| 16 | +2017-03-xx - xxxxxxx - lavu 55.34.0 - hwcontext.h | |
| 17 | + Add av_hwdevice_ctx_create_derived(). | |
| 18 | + | |
| 16 | 19 | 2017-02-10 - xxxxxxx - lavu 55.33.0 - spherical.h |
| 17 | 20 | Add AV_SPHERICAL_EQUIRECTANGULAR_TILE, av_spherical_tile_bounds(), |
| 18 | 21 | and projection-specific properties (bound_left, bound_top, bound_right, |
| @@ -65,6 +65,8 @@ static void hwdevice_ctx_free(void *opaque, uint8_t *data) · 64 unmodified lines | ||
| 65 | 65 | if (ctx->free) |
| 66 | 66 | ctx->free(ctx); |
| 67 | 67 | |
| 68 | + av_buffer_unref(&ctx->internal->source_device); | |
| 69 | + | |
| 68 | 70 | av_freep(&ctx->hwctx); |
| 69 | 71 | av_freep(&ctx->internal->priv); |
| 70 | 72 | av_freep(&ctx->internal); |
| @@ -535,6 +537,69 @@ fail: · 464 unmodified lines | ||
| 535 | 537 | return ret; |
| 536 | 538 | } |
| 537 | 539 | |
| 540 | +int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr, | |
| 541 | + enum AVHWDeviceType type, | |
| 542 | + AVBufferRef *src_ref, int flags) | |
| 543 | +{ | |
| 544 | + AVBufferRef *dst_ref = NULL, *tmp_ref; | |
| 545 | + AVHWDeviceContext *dst_ctx, *tmp_ctx; | |
| 546 | + int ret = 0; | |
| 547 | + | |
| 548 | + tmp_ref = src_ref; | |
| 549 | + while (tmp_ref) { | |
| 550 | + tmp_ctx = (AVHWDeviceContext*)tmp_ref->data; | |
| 551 | + if (tmp_ctx->type == type) { | |
| 552 | + dst_ref = av_buffer_ref(tmp_ref); | |
| 553 | + if (!dst_ref) { | |
| 554 | + ret = AVERROR(ENOMEM); | |
| 555 | + goto fail; | |
| 556 | + } | |
| 557 | + goto done; | |
| 558 | + } | |
| 559 | + tmp_ref = tmp_ctx->internal->source_device; | |
| 560 | + } | |
| 561 | + | |
| 562 | + dst_ref = av_hwdevice_ctx_alloc(type); | |
| 563 | + if (!dst_ref) { | |
| 564 | + ret = AVERROR(ENOMEM); | |
| 565 | + goto fail; | |
| 566 | + } | |
| 567 | + dst_ctx = (AVHWDeviceContext*)dst_ref->data; | |
| 568 | + | |
| 569 | + tmp_ref = src_ref; | |
| 570 | + while (tmp_ref) { | |
| 571 | + tmp_ctx = (AVHWDeviceContext*)tmp_ref->data; | |
| 572 | + if (dst_ctx->internal->hw_type->device_derive) { | |
| 573 | + ret = dst_ctx->internal->hw_type->device_derive(dst_ctx, | |
| 574 | + tmp_ctx, | |
| 575 | + flags); | |
| 576 | + if (ret == 0) { | |
| 577 | + dst_ctx->internal->source_device = av_buffer_ref(src_ref); | |
| 578 | + if (!dst_ctx->internal->source_device) { | |
| 579 | + ret = AVERROR(ENOMEM); | |
| 580 | + goto fail; | |
| 581 | + } | |
| 582 | + goto done; | |
| 583 | + } | |
| 584 | + if (ret != AVERROR(ENOSYS)) | |
| 585 | + goto fail; | |
| 586 | + } | |
| 587 | + tmp_ref = tmp_ctx->internal->source_device; | |
| 588 | + } | |
| 589 | + | |
| 590 | + ret = AVERROR(ENOSYS); | |
| 591 | + goto fail; | |
| 592 | + | |
| 593 | +done: | |
| 594 | + *dst_ref_ptr = dst_ref; | |
| 595 | + return 0; | |
| 596 | + | |
| 597 | +fail: | |
| 598 | + av_buffer_unref(&dst_ref); | |
| 599 | + *dst_ref_ptr = NULL; | |
| 600 | + return ret; | |
| 601 | +} | |
| 602 | + | |
| 538 | 603 | static void ff_hwframe_unmap(void *opaque, uint8_t *data) |
| 539 | 604 | { |
| 540 | 605 | HWMapDescriptor *hwmap = (HWMapDescriptor*)data; |
| @@ -268,6 +268,32 @@ int av_hwdevice_ctx_init(AVBufferRef *ref); · 267 unmodified lines | ||
| 268 | 268 | int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type, |
| 269 | 269 | const char *device, AVDictionary *opts, int flags); |
| 270 | 270 | |
| 271 | +/** | |
| 272 | + * Create a new device of the specified type from an existing device. | |
| 273 | + * | |
| 274 | + * If the source device is a device of the target type or was originally | |
| 275 | + * derived from such a device (possibly through one or more intermediate | |
| 276 | + * devices of other types), then this will return a reference to the | |
| 277 | + * existing device of the same type as is requested. | |
| 278 | + * | |
| 279 | + * Otherwise, it will attempt to derive a new device from the given source | |
| 280 | + * device. If direct derivation to the new type is not implemented, it will | |
| 281 | + * attempt the same derivation from each ancestor of the source device in | |
| 282 | + * turn looking for an implemented derivation method. | |
| 283 | + * | |
| 284 | + * @param dst_ctx On success, a reference to the newly-created | |
| 285 | + * AVHWDeviceContext. | |
| 286 | + * @param type The type of the new device to create. | |
| 287 | + * @param src_ctx A reference to an existing AVHWDeviceContext which will be | |
| 288 | + * used to create the new device. | |
| 289 | + * @param flags Currently unused; should be set to zero. | |
| 290 | + * @return Zero on success, a negative AVERROR code on failure. | |
| 291 | + */ | |
| 292 | +int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ctx, | |
| 293 | + enum AVHWDeviceType type, | |
| 294 | + AVBufferRef *src_ctx, int flags); | |
| 295 | + | |
| 296 | + | |
| 271 | 297 | /** |
| 272 | 298 | * Allocate an AVHWFramesContext tied to a given device context. |
| 273 | 299 | * |
| @@ -66,6 +66,8 @@ typedef struct HWContextType { · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | int (*device_create)(AVHWDeviceContext *ctx, const char *device, |
| 68 | 68 | AVDictionary *opts, int flags); |
| 69 | + int (*device_derive)(AVHWDeviceContext *dst_ctx, | |
| 70 | + AVHWDeviceContext *src_ctx, int flags); | |
| 69 | 71 | |
| 70 | 72 | int (*device_init)(AVHWDeviceContext *ctx); |
| 71 | 73 | void (*device_uninit)(AVHWDeviceContext *ctx); |
| @@ -95,6 +97,12 @@ typedef struct HWContextType { · 23 unmodified lines | ||
| 95 | 97 | struct AVHWDeviceInternal { |
| 96 | 98 | const HWContextType *hw_type; |
| 97 | 99 | void *priv; |
| 100 | + | |
| 101 | + /** | |
| 102 | + * For a derived device, a reference to the original device | |
| 103 | + * context it was derived from. | |
| 104 | + */ | |
| 105 | + AVBufferRef *source_device; | |
| 98 | 106 | }; |
| 99 | 107 | |
| 100 | 108 | struct AVHWFramesInternal { |
| @@ -54,7 +54,7 @@ · 53 unmodified lines | ||
| 54 | 54 | */ |
| 55 | 55 | |
| 56 | 56 | #define LIBAVUTIL_VERSION_MAJOR 55 |
| 57 | −#define LIBAVUTIL_VERSION_MINOR 33 | |
| 57 | +#define LIBAVUTIL_VERSION_MINOR 34 | |
| 58 | 58 | #define LIBAVUTIL_VERSION_MICRO 0 |
| 59 | 59 | |
| 60 | 60 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |