mirror of
https://github.com/mpv-player/mpv
synced 2025-01-03 13:32:16 +00:00
mp_image_pool: add helper functions for FFmpeg hw frames pools
FFmpeg has its own rather "special" image pools (AVHWFramesContext) specifically for hardware decoding. So it's not really practical to use our own pool implementation. Add these helpers, which make it easier to use FFmpeg's code in mpv.
This commit is contained in:
parent
0536ef306c
commit
cda7203934
@ -344,3 +344,76 @@ done:
|
||||
mp_image_copy_attributes(hw_img, src);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool mp_update_av_hw_frames_pool(struct AVBufferRef **hw_frames_ctx,
|
||||
struct AVBufferRef *hw_device_ctx,
|
||||
int imgfmt, int sw_imgfmt, int w, int h)
|
||||
{
|
||||
enum AVPixelFormat format = imgfmt2pixfmt(imgfmt);
|
||||
enum AVPixelFormat sw_format = imgfmt2pixfmt(sw_imgfmt);
|
||||
|
||||
if (format == AV_PIX_FMT_NONE || sw_format == AV_PIX_FMT_NONE ||
|
||||
!hw_device_ctx || w < 1 || h < 1)
|
||||
{
|
||||
av_buffer_unref(hw_frames_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*hw_frames_ctx) {
|
||||
AVHWFramesContext *hw_frames = (void *)(*hw_frames_ctx)->data;
|
||||
|
||||
if (hw_frames->device_ref->data != hw_device_ctx->data ||
|
||||
hw_frames->format != format || hw_frames->sw_format != sw_format ||
|
||||
hw_frames->width != w || hw_frames->height != h)
|
||||
av_buffer_unref(hw_frames_ctx);
|
||||
}
|
||||
|
||||
if (!*hw_frames_ctx) {
|
||||
*hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
|
||||
if (!*hw_frames_ctx)
|
||||
return false;
|
||||
|
||||
AVHWFramesContext *hw_frames = (void *)(*hw_frames_ctx)->data;
|
||||
hw_frames->format = format;
|
||||
hw_frames->sw_format = sw_format;
|
||||
hw_frames->width = w;
|
||||
hw_frames->height = h;
|
||||
if (av_hwframe_ctx_init(*hw_frames_ctx) < 0) {
|
||||
av_buffer_unref(hw_frames_ctx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct mp_image *mp_av_pool_image_hw_upload(struct AVBufferRef *hw_frames_ctx,
|
||||
struct mp_image *src)
|
||||
{
|
||||
AVFrame *av_frame = av_frame_alloc();
|
||||
if (!av_frame)
|
||||
return NULL;
|
||||
if (av_hwframe_get_buffer(hw_frames_ctx, av_frame, 0) < 0) {
|
||||
av_frame_free(&av_frame);
|
||||
return NULL;
|
||||
}
|
||||
struct mp_image *dst = mp_image_from_av_frame(av_frame);
|
||||
av_frame_free(&av_frame);
|
||||
if (!dst)
|
||||
return NULL;
|
||||
|
||||
if (dst->w < src->w || dst->h < src->h) {
|
||||
talloc_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp_image_set_size(dst, src->w, src->h);
|
||||
|
||||
if (!mp_image_hw_upload(dst, src)) {
|
||||
talloc_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp_image_copy_attributes(dst, src);
|
||||
return dst;
|
||||
}
|
||||
|
@ -31,4 +31,12 @@ struct mp_image *mp_image_hw_download(struct mp_image *img,
|
||||
|
||||
bool mp_image_hw_upload(struct mp_image *hw_img, struct mp_image *src);
|
||||
|
||||
struct AVBufferRef;
|
||||
bool mp_update_av_hw_frames_pool(struct AVBufferRef **hw_frames_ctx,
|
||||
struct AVBufferRef *hw_device_ctx,
|
||||
int imgfmt, int sw_imgfmt, int w, int h);
|
||||
|
||||
struct mp_image *mp_av_pool_image_hw_upload(struct AVBufferRef *hw_frames_ctx,
|
||||
struct mp_image *src);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user