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.
This commit is contained in:
wm4 2019-10-02 21:07:14 +02:00
parent 25e70f4743
commit 95e13e3d3e
2 changed files with 22 additions and 11 deletions

View File

@ -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)

View File

@ -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;