extern "C" {
#include <libavformat/avformat.h>
+#include <libavutil/channel_layout.h>
}
#include "defs.h"
add_stream(HTTPD::StreamID{ HTTPD::MULTICAM_STREAM, 0 });
// Initialize VA-API.
+ VAConfigID config_id_422, config_id_420;
string error;
va_dpy = try_open_va(va_display, { VAProfileJPEGBaseline }, VAEntrypointEncPicture,
{
encoder_thread = thread(&MJPEGEncoder::encoder_thread_func, this);
if (va_dpy != nullptr) {
+ va_pool.reset(new VAResourcePool(va_dpy->va_dpy, uyvy_format, nv12_format, config_id_422, config_id_420, /*with_data_buffer=*/true));
va_receiver_thread = thread(&MJPEGEncoder::va_receiver_thread_func, this);
}
VABufferID buf;
};
-MJPEGEncoder::VAResources MJPEGEncoder::get_va_resources(unsigned width, unsigned height, uint32_t fourcc)
-{
- {
- lock_guard<mutex> lock(va_resources_mutex);
- for (auto it = va_resources_freelist.begin(); it != va_resources_freelist.end(); ++it) {
- if (it->width == width && it->height == height && it->fourcc == fourcc) {
- VAResources ret = *it;
- va_resources_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_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_dpy, VA_RT_FORMAT_YUV420, width, height, &ret.surface, 1, &attrib, 1);
- config_id = config_id_420;
- }
-
- va_status = vaCreateContext(va_dpy->va_dpy, config_id, width, height, 0, &ret.surface, 1, &ret.context);
- CHECK_VASTATUS(va_status, "vaCreateContext");
-
- va_status = vaCreateBuffer(va_dpy->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->va_dpy, &uyvy_format, width, height, &ret.image);
- CHECK_VASTATUS(va_status, "vaCreateImage");
- } else {
- assert(fourcc == VA_FOURCC_NV12);
- va_status = vaCreateImage(va_dpy->va_dpy, &nv12_format, width, height, &ret.image);
- CHECK_VASTATUS(va_status, "vaCreateImage");
- }
-
- return ret;
-}
-
-void MJPEGEncoder::release_va_resources(MJPEGEncoder::VAResources resources)
-{
- lock_guard<mutex> lock(va_resources_mutex);
- if (va_resources_freelist.size() > 50) {
- auto it = va_resources_freelist.end();
- --it;
-
- VAStatus va_status = vaDestroyBuffer(va_dpy->va_dpy, it->data_buffer);
- CHECK_VASTATUS(va_status, "vaDestroyBuffer");
-
- 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_status = vaDestroyImage(va_dpy->va_dpy, it->image.image_id);
- CHECK_VASTATUS(va_status, "vaDestroyImage");
-
- va_resources_freelist.erase(it);
- }
-
- va_resources_freelist.push_front(resources);
-}
-
namespace {
void push16(uint16_t val, string *str)
unsigned width = qf.video_format.width;
unsigned height = qf.video_format.height;
- VAResources resources;
+ VAResourcePool::VAResources resources;
ReleaseVAResources release;
if (userdata->data_copy_current_src == PBOFrameAllocator::Userdata::FROM_VA_API) {
assert(is_uyvy(qf.frame));
} else {
assert(userdata->data_copy_current_src == PBOFrameAllocator::Userdata::FROM_MALLOC);
if (is_uyvy(qf.frame)) {
- resources = get_va_resources(width, height, VA_FOURCC_UYVY);
+ resources = va_pool->get_va_resources(width, height, VA_FOURCC_UYVY);
} else {
assert(is_i420(qf.frame));
- resources = get_va_resources(width, height, VA_FOURCC_NV12);
+ resources = va_pool->get_va_resources(width, height, VA_FOURCC_NV12);
}
- release = ReleaseVAResources(this, resources);
+ release = ReleaseVAResources(va_pool.get(), resources);
}
int y_h_samp_factor, y_v_samp_factor;