X-Git-Url: https://git.sesse.net/?p=nageru;a=blobdiff_plain;f=futatabi%2Fvaapi_jpeg_decoder.cpp;fp=futatabi%2Fvaapi_jpeg_decoder.cpp;h=8fe1ac88f7fc46f4ddb0af10895115bd52a05dd7;hp=0540db7da82061ff314ad26bdba2c76cb2cdca5a;hb=8850f9468d6a1727e7be302d2a9b4360f69210cc;hpb=58c351c4a2afa8377047c89ca55c367156fe36f9 diff --git a/futatabi/vaapi_jpeg_decoder.cpp b/futatabi/vaapi_jpeg_decoder.cpp index 0540db7..8fe1ac8 100644 --- a/futatabi/vaapi_jpeg_decoder.cpp +++ b/futatabi/vaapi_jpeg_decoder.cpp @@ -6,6 +6,7 @@ #include "pbo_pool.h" #include "shared/memcpy_interleaved.h" #include "shared/va_display.h" +#include "shared/va_resource_pool.h" #include #include @@ -29,30 +30,9 @@ using namespace std; static unique_ptr va_dpy; -static VAConfigID config_id; -static VAImageFormat uyvy_format; -bool vaapi_jpeg_decoding_usable = false; - -struct VAResources { - unsigned width, height; - VASurfaceID surface; - VAContextID context; - VAImage image; -}; -static list va_resources_freelist; -static mutex va_resources_mutex; - -#define CHECK_VASTATUS(va_status, func) \ - if (va_status != VA_STATUS_SUCCESS) { \ - fprintf(stderr, "%s:%d (%s) failed with %d\n", __func__, __LINE__, func, va_status); \ - abort(); \ - } +static unique_ptr va_pool; -#define CHECK_VASTATUS_RET(va_status, func) \ - if (va_status != VA_STATUS_SUCCESS) { \ - fprintf(stderr, "%s:%d (%s) failed with %d\n", __func__, __LINE__, func, va_status); \ - return nullptr; \ - } +bool vaapi_jpeg_decoding_usable = false; // From libjpeg (although it's of course identical between implementations). static const int jpeg_natural_order[DCTSIZE2] = { @@ -66,85 +46,24 @@ static const int jpeg_natural_order[DCTSIZE2] = { 53, 60, 61, 54, 47, 55, 62, 63, }; -VAResources get_va_resources(unsigned width, unsigned height) -{ - { - lock_guard lock(va_resources_mutex); - for (auto it = va_resources_freelist.begin(); it != va_resources_freelist.end(); ++it) { - if (it->width == width && it->height == height) { - VAResources ret = *it; - va_resources_freelist.erase(it); - return ret; - } - } - } - - VAResources ret; - - ret.width = width; - ret.height = height; - - VAStatus va_status = vaCreateSurfaces(va_dpy->va_dpy, VA_RT_FORMAT_YUV422, - width, height, - &ret.surface, 1, nullptr, 0); - CHECK_VASTATUS(va_status, "vaCreateSurfaces"); - - va_status = vaCreateContext(va_dpy->va_dpy, config_id, width, height, 0, &ret.surface, 1, &ret.context); - CHECK_VASTATUS(va_status, "vaCreateContext"); - - va_status = vaCreateImage(va_dpy->va_dpy, &uyvy_format, width, height, &ret.image); - CHECK_VASTATUS(va_status, "vaCreateImage"); - - return ret; -} - -void release_va_resources(VAResources resources) +static unique_ptr try_open_va_mjpeg(const string &va_display) { - lock_guard lock(va_resources_mutex); - if (va_resources_freelist.size() > 10) { - auto it = va_resources_freelist.end(); - --it; - - VAStatus va_status = vaDestroyImage(va_dpy->va_dpy, it->image.image_id); - CHECK_VASTATUS(va_status, "vaDestroyImage"); - - va_status = vaDestroyContext(va_dpy->va_dpy, it->context); - CHECK_VASTATUS(va_status, "vaDestroyContext"); - - va_status = vaDestroySurfaces(va_dpy->va_dpy, &it->surface, 1); - CHECK_VASTATUS(va_status, "vaDestroySurfaces"); + VAConfigID config_id_422, config_id_420; + VAImageFormat uyvy_format, nv12_format; - va_resources_freelist.erase(it); - } - - va_resources_freelist.push_front(resources); -} - -// RAII wrapper to release VAResources on return (even on error). -class ReleaseVAResources { -public: - ReleaseVAResources(const VAResources &resources) - : resources(resources) {} - ~ReleaseVAResources() - { - if (!committed) { - release_va_resources(resources); - } + // Seemingly VA_FOURCC_422H is no good for vaGetImage(). :-/ + unique_ptr va_dpy = + try_open_va(va_display, { VAProfileJPEGBaseline }, VAEntrypointVLD, + { { "4:2:2", VA_RT_FORMAT_YUV422, VA_FOURCC_UYVY, &config_id_422, &uyvy_format }, + { "4:2:0", VA_RT_FORMAT_YUV420, VA_FOURCC_NV12, &config_id_420, &nv12_format } }, + /*chosen_profile=*/nullptr, /*error=*/nullptr); + if (va_dpy == nullptr) { + return va_dpy; } - void commit() { committed = true; } - -private: - const VAResources &resources; - bool committed = false; -}; + va_pool.reset(new VAResourcePool(va_dpy->va_dpy, uyvy_format, nv12_format, config_id_422, config_id_420, /*with_data_buffer=*/false)); -static unique_ptr try_open_va_mjpeg(const string &va_display) -{ - // Seemingly VA_FOURCC_422H is no good for vaGetImage(). :-/ - return try_open_va(va_display, { VAProfileJPEGBaseline }, VAEntrypointVLD, - { { "4:2:2", VA_RT_FORMAT_YUV422, VA_FOURCC_UYVY, &config_id, &uyvy_format } }, - /*chosen_profile=*/nullptr, /*error=*/nullptr); + return va_dpy; } string get_usable_va_display() @@ -280,8 +199,8 @@ shared_ptr decode_jpeg_vaapi(const string &jpeg) pic_param.color_space = 0; // YUV. pic_param.rotation = VA_ROTATION_NONE; - VAResources resources = get_va_resources(dinfo.image_width, dinfo.image_height); - ReleaseVAResources release(resources); + VAResourcePool::VAResources resources = va_pool->get_va_resources(dinfo.image_width, dinfo.image_height, VA_FOURCC_UYVY); + ReleaseVAResources release(va_pool.get(), resources); VABufferID pic_param_buffer; VAStatus va_status = vaCreateBuffer(va_dpy->va_dpy, resources.context, VAPictureParameterBufferType, sizeof(pic_param), 1, &pic_param, &pic_param_buffer);