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 | API changes, most recent first: | 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 | 2017-02-10 - xxxxxxx - lavu 55.33.0 - spherical.h | 19 | 2017-02-10 - xxxxxxx - lavu 55.33.0 - spherical.h |
| 17 | Add AV_SPHERICAL_EQUIRECTANGULAR_TILE, av_spherical_tile_bounds(), | 20 | Add AV_SPHERICAL_EQUIRECTANGULAR_TILE, av_spherical_tile_bounds(), |
| 18 | and projection-specific properties (bound_left, bound_top, bound_right, | 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 | if (ctx->free) | 65 | if (ctx->free) |
| 66 | ctx->free(ctx); | 66 | ctx->free(ctx); |
| 67 | 67 | ||
| 68 | av_buffer_unref(&ctx->internal->source_device); | ||
| 69 | |||
| 68 | av_freep(&ctx->hwctx); | 70 | av_freep(&ctx->hwctx); |
| 69 | av_freep(&ctx->internal->priv); | 71 | av_freep(&ctx->internal->priv); |
| 70 | av_freep(&ctx->internal); | 72 | av_freep(&ctx->internal); |
| @@ -535,6 +537,69 @@ fail: · 464 unmodified lines | |||
| 535 | return ret; | 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 | static void ff_hwframe_unmap(void *opaque, uint8_t *data) | 603 | static void ff_hwframe_unmap(void *opaque, uint8_t *data) |
| 539 | { | 604 | { |
| 540 | HWMapDescriptor *hwmap = (HWMapDescriptor*)data; | 605 | HWMapDescriptor *hwmap = (HWMapDescriptor*)data; |
| @@ -268,6 +268,32 @@ int av_hwdevice_ctx_init(AVBufferRef *ref); · 267 unmodified lines | |||
| 268 | int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type, | 268 | int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type, |
| 269 | const char *device, AVDictionary *opts, int flags); | 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 | * Allocate an AVHWFramesContext tied to a given device context. | 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 | int (*device_create)(AVHWDeviceContext *ctx, const char *device, | 67 | int (*device_create)(AVHWDeviceContext *ctx, const char *device, |
| 68 | AVDictionary *opts, int flags); | 68 | AVDictionary *opts, int flags); |
| 69 | int (*device_derive)(AVHWDeviceContext *dst_ctx, | ||
| 70 | AVHWDeviceContext *src_ctx, int flags); | ||
| 69 | 71 | ||
| 70 | int (*device_init)(AVHWDeviceContext *ctx); | 72 | int (*device_init)(AVHWDeviceContext *ctx); |
| 71 | void (*device_uninit)(AVHWDeviceContext *ctx); | 73 | void (*device_uninit)(AVHWDeviceContext *ctx); |
| @@ -95,6 +97,12 @@ typedef struct HWContextType { · 23 unmodified lines | |||
| 95 | struct AVHWDeviceInternal { | 97 | struct AVHWDeviceInternal { |
| 96 | const HWContextType *hw_type; | 98 | const HWContextType *hw_type; |
| 97 | void *priv; | 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 | struct AVHWFramesInternal { | 108 | struct AVHWFramesInternal { |
| @@ -54,7 +54,7 @@ · 53 unmodified lines | |||
| 54 | */ | 54 | */ |
| 55 | 55 | ||
| 56 | #define LIBAVUTIL_VERSION_MAJOR 55 | 56 | #define LIBAVUTIL_VERSION_MAJOR 55 |
| 57 | #define LIBAVUTIL_VERSION_MINOR 33 | 57 | #define LIBAVUTIL_VERSION_MINOR 34 |
| 58 | #define LIBAVUTIL_VERSION_MICRO 0 | 58 | #define LIBAVUTIL_VERSION_MICRO 0 |
| 59 | 59 | ||
| 60 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | 60 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |