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