From 95e13e3d3e3f00ee574477e3abe3c2f497e341cb Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 2 Oct 2019 21:07:14 +0200 Subject: mp_image_pool: expose a function for reporting hw download format Basically predicts what mp_image_hw_download() will do. It's pretty simple if it gets the full mp_image. (Taking just a imgfmt would make this pretty hard/impossible or inaccurate.) Used in one of the following commits. --- video/mp_image_pool.c | 31 ++++++++++++++++++++----------- video/mp_image_pool.h | 2 ++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/video/mp_image_pool.c b/video/mp_image_pool.c index 17d1087740..8aa584b33e 100644 --- a/video/mp_image_pool.c +++ b/video/mp_image_pool.c @@ -253,25 +253,19 @@ void mp_image_pool_set_lru(struct mp_image_pool *pool) pool->use_lru = true; } - -// Copies the contents of the HW surface img to system memory and retuns it. -// If swpool is not NULL, it's used to allocate the target image. -// img must be a hw surface with a AVHWFramesContext attached. -// The returned image is cropped as needed. -// Returns NULL on failure. -struct mp_image *mp_image_hw_download(struct mp_image *src, - struct mp_image_pool *swpool) +// Return the sw image format mp_image_hw_download() would use. This can be +// different from src->params.hw_subfmt in obscure cases. +int mp_image_hw_download_get_sw_format(struct mp_image *src) { if (!src->hwctx) - return NULL; - AVHWFramesContext *fctx = (void *)src->hwctx->data; + return 0; // Try to find the first format which we can apparently use. int imgfmt = 0; enum AVPixelFormat *fmts; if (av_hwframe_transfer_get_formats(src->hwctx, AV_HWFRAME_TRANSFER_DIRECTION_FROM, &fmts, 0) < 0) - return NULL; + return 0; for (int n = 0; fmts[n] != AV_PIX_FMT_NONE; n++) { imgfmt = pixfmt2imgfmt(fmts[n]); if (imgfmt) @@ -279,9 +273,24 @@ struct mp_image *mp_image_hw_download(struct mp_image *src, } av_free(fmts); + return imgfmt; +} + +// Copies the contents of the HW surface src to system memory and retuns it. +// If swpool is not NULL, it's used to allocate the target image. +// src must be a hw surface with a AVHWFramesContext attached. +// The returned image is cropped as needed. +// Returns NULL on failure. +struct mp_image *mp_image_hw_download(struct mp_image *src, + struct mp_image_pool *swpool) +{ + int imgfmt = mp_image_hw_download_get_sw_format(src); if (!imgfmt) return NULL; + assert(src->hwctx); + AVHWFramesContext *fctx = (void *)src->hwctx->data; + struct mp_image *dst = mp_image_pool_get(swpool, imgfmt, fctx->width, fctx->height); if (!dst) diff --git a/video/mp_image_pool.h b/video/mp_image_pool.h index 7c9f0463cb..3c7e6221d1 100644 --- a/video/mp_image_pool.h +++ b/video/mp_image_pool.h @@ -29,6 +29,8 @@ bool mp_image_pool_make_writeable(struct mp_image_pool *pool, struct mp_image *mp_image_hw_download(struct mp_image *img, struct mp_image_pool *swpool); +int mp_image_hw_download_get_sw_format(struct mp_image *img); + bool mp_image_hw_upload(struct mp_image *hw_img, struct mp_image *src); struct AVBufferRef; -- cgit v1.2.3