- lock_guard<mutex> 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");
-
- 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);
- }
- }
-
- void commit() { committed = true; }
-
-private:
- const VAResources &resources;
- bool committed = false;
-};
-
-unique_ptr<VADisplayWithCleanup> va_open_display(const string &va_display)
-{
- if (va_display.empty() || va_display[0] != '/') { // An X display.
- Display *x11_display = XOpenDisplay(va_display.empty() ? nullptr : va_display.c_str());
- if (x11_display == nullptr) {
- fprintf(stderr, "error: can't connect to X server!\n");
- return nullptr;
- }
-
- unique_ptr<VADisplayWithCleanup> ret(new VADisplayWithCleanup);
- ret->x11_display = x11_display;
- ret->va_dpy = vaGetDisplay(x11_display);
- if (ret->va_dpy == nullptr) {
- return nullptr;
- }
- return ret;
- } else { // A DRM node on the filesystem (e.g. /dev/dri/renderD128).
- int drm_fd = open(va_display.c_str(), O_RDWR);
- if (drm_fd == -1) {
- perror(va_display.c_str());
- return nullptr;
- }
- unique_ptr<VADisplayWithCleanup> ret(new VADisplayWithCleanup);
- ret->drm_fd = drm_fd;
- ret->va_dpy = vaGetDisplayDRM(drm_fd);
- if (ret->va_dpy == nullptr) {
- return nullptr;
- }
- return ret;
- }
-}
-
-unique_ptr<VADisplayWithCleanup> try_open_va(const string &va_display, string *error)
-{
- unique_ptr<VADisplayWithCleanup> va_dpy = va_open_display(va_display);
+ VAConfigID config_id_422, config_id_420;
+ VAImageFormat uyvy_format, nv12_format;
+
+ // Seemingly VA_FOURCC_422H is no good for vaGetImage(). :-/
+ unique_ptr<VADisplayWithCleanup> 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);