#include "jpeg_destroyer.h"
#include "jpeg_frame.h"
#include "jpeglib_error_wrapper.h"
+#include "pbo_pool.h"
#include "shared/memcpy_interleaved.h"
#include <X11/Xlib.h>
#include <va/va_drm.h>
#include <va/va_x11.h>
+#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
+
using namespace std;
static unique_ptr<VADisplayWithCleanup> va_dpy;
}
JPEGDestroyer destroy_dinfo(&dinfo);
+ jpeg_save_markers(&dinfo, JPEG_APP0 + 1, 0xFFFF);
+
jpeg_mem_src(&dinfo, reinterpret_cast<const unsigned char *>(jpeg.data()), jpeg.size());
if (!error_mgr.run([&dinfo] { jpeg_read_header(&dinfo, true); })) {
return nullptr;
#else
// Convert Y'CbCr to separate Y' and CbCr.
frame->is_semiplanar = true;
- frame->y.reset(new uint8_t[dinfo.image_width * dinfo.image_height]);
- frame->cbcr.reset(new uint8_t[dinfo.image_width * dinfo.image_height]);
+
+ PBO pbo = global_pbo_pool->alloc_pbo();
+ size_t cbcr_offset = dinfo.image_width * dinfo.image_height;
+ uint8_t *y_pix = pbo.ptr;
+ uint8_t *cbcr_pix = pbo.ptr + cbcr_offset;
+
const uint8_t *src = (const uint8_t *)mapped + resources.image.offsets[0];
if (resources.image.pitches[0] == dinfo.image_width * 2) {
- memcpy_interleaved(frame->cbcr.get(), frame->y.get(), src, dinfo.image_width * dinfo.image_height * 2);
+ memcpy_interleaved(cbcr_pix, y_pix, src, dinfo.image_width * dinfo.image_height * 2);
} else {
for (unsigned y = 0; y < dinfo.image_height; ++y) {
- memcpy_interleaved(frame->cbcr.get() + y * dinfo.image_width, frame->y.get() + y * dinfo.image_width,
+ memcpy_interleaved(cbcr_pix + y * dinfo.image_width, y_pix + y * dinfo.image_width,
src + y * resources.image.pitches[0], dinfo.image_width * 2);
}
}
+
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.pbo);
+ frame->y = create_texture_2d(dinfo.image_width, dinfo.image_height, GL_R8, GL_RED, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
+ frame->cbcr = create_texture_2d(dinfo.image_width / 2, dinfo.image_height, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, BUFFER_OFFSET(cbcr_offset));
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ glFlushMappedNamedBufferRange(pbo.pbo, 0, dinfo.image_width * dinfo.image_height * 2);
+ glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
+ pbo.upload_done = RefCountedGLsync(GL_SYNC_GPU_COMMANDS_COMPLETE, /*flags=*/0);
+ frame->uploaded_ui_thread = pbo.upload_done;
+ frame->uploaded_interpolation = pbo.upload_done;
+ global_pbo_pool->release_pbo(move(pbo));
#endif
frame->width = dinfo.image_width;
frame->height = dinfo.image_height;
frame->chroma_subsampling_x = 2;
frame->chroma_subsampling_y = 1;
- frame->pitch_y = dinfo.image_width;
- frame->pitch_chroma = dinfo.image_width / 2;
+
+ if (dinfo.marker_list != nullptr &&
+ dinfo.marker_list->marker == JPEG_APP0 + 1 &&
+ dinfo.marker_list->data_length >= 4 &&
+ memcmp(dinfo.marker_list->data, "Exif", 4) == 0) {
+ frame->exif_data.assign(reinterpret_cast<char *>(dinfo.marker_list->data),
+ dinfo.marker_list->data_length);
+ }
va_status = vaUnmapBuffer(va_dpy->va_dpy, resources.image.buf);
CHECK_VASTATUS_RET(va_status, "vaUnmapBuffer");