1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
#ifndef _VA_RESOURCE_POOL
#define _VA_RESOURCE_POOL 1
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <va/va.h>
#include <list>
#include <mutex>
#define CHECK_VASTATUS(va_status, func) \
if (va_status != VA_STATUS_SUCCESS) { \
fprintf(stderr, "%s:%d (%s) failed: %s\n", __func__, __LINE__, func, vaErrorStr(va_status)); \
exit(1); \
}
#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; \
}
class VAResourcePool {
public:
struct VAResources {
unsigned width, height;
uint32_t fourcc;
VASurfaceID surface;
VAContextID context;
VABufferID data_buffer;
VAImage image;
};
VAResourcePool(VADisplay va_dpy, VAImageFormat uyvy_format, VAImageFormat nv12_format, VAConfigID config_id_422, VAConfigID config_id_420, bool with_data_buffer)
: va_dpy(va_dpy),
uyvy_format(uyvy_format),
nv12_format(nv12_format),
config_id_422(config_id_422),
config_id_420(config_id_420),
with_data_buffer(with_data_buffer) {}
VAResources get_va_resources(unsigned width, unsigned height, uint32_t fourcc);
void release_va_resources(VAResources resources);
private:
const VADisplay va_dpy;
VAImageFormat uyvy_format, nv12_format;
const VAConfigID config_id_422, config_id_420;
const bool with_data_buffer;
std::mutex mu;
std::list<VAResources> freelist; // Under mu.
};
// RAII wrapper to release VAResources on return (even on error).
class ReleaseVAResources {
public:
ReleaseVAResources() : committed(true) {}
ReleaseVAResources(VAResourcePool *pool, const VAResourcePool::VAResources &resources)
: pool(pool), resources(resources) {}
ReleaseVAResources(ReleaseVAResources &) = delete;
ReleaseVAResources(ReleaseVAResources &&other)
: pool(other.pool), resources(other.resources), committed(other.committed) {
other.commit();
}
ReleaseVAResources &operator= (ReleaseVAResources &) = delete;
ReleaseVAResources &operator= (ReleaseVAResources &&other) {
if (!committed) {
pool->release_va_resources(resources);
}
pool = other.pool;
resources = std::move(other.resources);
committed = other.committed;
other.commit();
return *this;
}
~ReleaseVAResources()
{
if (!committed) {
pool->release_va_resources(resources);
}
}
void commit() { committed = true; }
private:
VAResourcePool *pool = nullptr;
VAResourcePool::VAResources resources;
bool committed = false;
};
#endif // !defined(_VA_RESOURCE_POOL)
|