X-Git-Url: https://git.sesse.net/?p=nageru;a=blobdiff_plain;f=shared%2Fva_resource_pool.cpp;fp=shared%2Fva_resource_pool.cpp;h=f23aca070b9b8b62681af03dc9f6c7d6c8dac526;hp=0000000000000000000000000000000000000000;hb=8850f9468d6a1727e7be302d2a9b4360f69210cc;hpb=58c351c4a2afa8377047c89ca55c367156fe36f9 diff --git a/shared/va_resource_pool.cpp b/shared/va_resource_pool.cpp new file mode 100644 index 0000000..f23aca0 --- /dev/null +++ b/shared/va_resource_pool.cpp @@ -0,0 +1,92 @@ + +#include + +#include "shared/va_resource_pool.h" + +using namespace std; + +VAResourcePool::VAResources VAResourcePool::get_va_resources(unsigned width, unsigned height, uint32_t fourcc) +{ + { + lock_guard lock(mu); + for (auto it = freelist.begin(); it != freelist.end(); ++it) { + if (it->width == width && it->height == height && it->fourcc == fourcc) { + VAResources ret = *it; + freelist.erase(it); + return ret; + } + } + } + + VAResources ret; + + ret.width = width; + ret.height = height; + ret.fourcc = fourcc; + + VASurfaceAttrib attrib; + attrib.flags = VA_SURFACE_ATTRIB_SETTABLE; + attrib.type = VASurfaceAttribPixelFormat; + attrib.value.type = VAGenericValueTypeInteger; + attrib.value.value.i = fourcc; + + VAStatus va_status; + VAConfigID config_id; + if (fourcc == VA_FOURCC_UYVY) { + va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV422, width, height, &ret.surface, 1, &attrib, 1); + config_id = config_id_422; + } else { + assert(fourcc == VA_FOURCC_NV12); + va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, width, height, &ret.surface, 1, &attrib, 1); + config_id = config_id_420; + } + + va_status = vaCreateContext(va_dpy, config_id, width, height, 0, &ret.surface, 1, &ret.context); + CHECK_VASTATUS(va_status, "vaCreateContext"); + + if (with_data_buffer) { + va_status = vaCreateBuffer(va_dpy, ret.context, VAEncCodedBufferType, width * height * 3 + 8192, 1, nullptr, &ret.data_buffer); + CHECK_VASTATUS(va_status, "vaCreateBuffer"); + } + + if (fourcc == VA_FOURCC_UYVY) { + va_status = vaCreateImage(va_dpy, &uyvy_format, width, height, &ret.image); + CHECK_VASTATUS(va_status, "vaCreateImage"); + } else { + assert(fourcc == VA_FOURCC_NV12); + va_status = vaCreateImage(va_dpy, &nv12_format, width, height, &ret.image); + CHECK_VASTATUS(va_status, "vaCreateImage"); + } + + return ret; +} + +void VAResourcePool::release_va_resources(VAResourcePool::VAResources resources) +{ + lock_guard lock(mu); + if (freelist.size() > 50) { + auto it = freelist.end(); + --it; + + VAStatus va_status; + + if (with_data_buffer) { + va_status = vaDestroyBuffer(va_dpy, it->data_buffer); + CHECK_VASTATUS(va_status, "vaDestroyBuffer"); + } + + va_status = vaDestroyContext(va_dpy, it->context); + CHECK_VASTATUS(va_status, "vaDestroyContext"); + + va_status = vaDestroySurfaces(va_dpy, &it->surface, 1); + CHECK_VASTATUS(va_status, "vaDestroySurfaces"); + + va_status = vaDestroyImage(va_dpy, it->image.image_id); + CHECK_VASTATUS(va_status, "vaDestroyImage"); + + freelist.erase(it); + } + + freelist.push_front(resources); +} +