46 for (
int i = 0; i < 4; i++) {
82 void *src_buffer = NULL;
83 void *dst_buffer = NULL;
89 dst_buffer = malloc(src->
m_size[
object]);
90 src_buffer = mmap(NULL, src->
m_size[
object], PROT_READ, MAP_SHARED, src->
m_dmaBufHandle[
object], 0);
91 if (src_buffer == MAP_FAILED) {
92 LOGERROR(
"drmbuffer: %s (clone): cannot map buffer size %d prime_fd %d (%d): %m",
97 LOGDEBUG2(
L_GRAB,
"drmbuffer: %s (clone): Copy %p to %p", __FUNCTION__, src_buffer, dst_buffer);
98 memcpy(dst_buffer, src_buffer, src->
m_size[
object]);
99 munmap(src_buffer, src->
m_size[
object]);
100 for (
int plane = 0; plane <
m_numPlanes; plane++) {
102 m_pPlane[plane] = (uint8_t *)dst_buffer;
103 LOGDEBUG2(
L_GRAB,
"drmbuffer: %s (clone): plane[%d] gets %p (object %d)", __FUNCTION__, plane, dst_buffer,
object);
108 for (
int plane = 0; plane <
m_numPlanes; plane++) {
109 dst_buffer = malloc(
m_size[plane]);
111 m_pPlane[plane] = (uint8_t *)dst_buffer;
115 for (
int plane = 0; plane <
m_numPlanes; plane++) {
116 LOGDEBUG2(
L_GRAB,
"drmbuffer: %s (clone): Cloned plane %d address %p pitch %d offset %d handle %d size %d",
143 for (
int i = 0; i < 4; i++) {
166 struct drm_mode_destroy_dumb dreq;
172 LOGERROR(
"drmbuffer: %s: failed unmap FB (%d): %m", __FUNCTION__, errno);
177 LOGERROR(
"drmbuffer: %s: cannot rm FB (%d): %m", __FUNCTION__, errno);
181 LOGERROR(
"drmbuffer: %s: error closing DMA-BUF handle %d (%d): %m", __FUNCTION__,
m_dmaBufHandle[0], errno);
186 memset(&dreq, 0,
sizeof(dreq));
189 if (drmIoctl(
m_drmDeviceFd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq) < 0)
190 LOGERROR(
"drmbuffer: %s: cannot destroy dumb buffer (%d): %m", __FUNCTION__, errno);
238 { DRM_FORMAT_NV12,
"NV12", 2, { { 8, 1, 1 }, { 16, 2, 2 } }, },
239 { DRM_FORMAT_YUV420,
"YU12", 3, { { 8, 1, 1 }, { 8, 2, 2 }, {8, 2, 2 } }, },
240 { DRM_FORMAT_ARGB8888,
"AR24", 1, { { 32, 1, 1 } }, },
243#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
270void cDrmBuffer::Setup(
int drmDeviceFd, uint32_t width, uint32_t height, uint32_t pixFmt, AVDRMFrameDescriptor *primedata,
bool closeHandleOnDestroy)
272 uint64_t modifier[4] = { 0, 0, 0, 0 };
273 uint32_t mod_flags = 0;
287 if (!primedata->nb_objects)
288 LOGFATAL(
"drmbuffer: %s: No primedata objects available!", __FUNCTION__);
290 AVDRMLayerDescriptor *layer = &primedata->layers[0];
300 for (
int object = 0;
object < primedata->nb_objects;
object++) {
301 if (drmPrimeFDToHandle(drmDeviceFd, primedata->objects[
object].fd, &
m_objectPrimeHandle[
object])) {
302 LOGFATAL(
"drmbuffer: %s: PRIMEDATA Failed to retrieve the Prime Handle %i size %zu (%d): %m", __FUNCTION__,
303 primedata->objects[
object].fd,
304 primedata->objects[
object].size, errno);
308 m_size[object] = primedata->objects[object].size;
315 for (
int plane = 0; plane < layer->nb_planes; plane++) {
316 int object = layer->planes[plane].object_index;
320 m_pitch[plane] = layer->planes[plane].pitch;
321 m_offset[plane] = layer->planes[plane].offset;
323 if (primedata->objects[
object].format_modifier)
324 modifier[plane] = primedata->objects[object].format_modifier;
330 if (modifier[0] && modifier[0] != DRM_FORMAT_MOD_INVALID)
331 mod_flags = DRM_MODE_FB_MODIFIERS;
335 LOGFATAL(
"drmbuffer: %s: No suitable format found!", __FUNCTION__);
345 struct drm_mode_create_dumb creq;
348 creq.bpp = plane_info->
bitspp;
354 if (drmIoctl(drmDeviceFd, DRM_IOCTL_MODE_CREATE_DUMB, &creq) < 0)
355 LOGFATAL(
"drmbuffer: %s: cannot create dumb buffer %dx%d@%d (%d): %m", __FUNCTION__,
356 creq.width, creq.height, creq.bpp, errno);
360 m_size[plane] = creq.size;
362 struct drm_mode_map_dumb mreq;
363 memset(&mreq, 0,
sizeof(
struct drm_mode_map_dumb));
366 if (drmIoctl(drmDeviceFd, DRM_IOCTL_MODE_MAP_DUMB, &mreq))
367 LOGFATAL(
"drmbuffer: %s: cannot prepare dumb buffer for mapping (%d): %m", __FUNCTION__, errno);
369 m_pPlane[plane] = (uint8_t *)mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, drmDeviceFd, mreq.offset);
372 LOGFATAL(
"drmbuffer: %s: cannot map dumb buffer (%d): %m", __FUNCTION__, errno);
386 LOGERROR(
"drmbuffer: %s: cannot create modifiers framebuffer (%d): %m", __FUNCTION__, errno);
393 LOGFATAL(
"drmbuffer: %s: cannot create framebuffer (%d): %m", __FUNCTION__, errno);
395 LOGDEBUG2(
L_DRM,
"drmbuffer: %s: Added %sFB fb_id %d width %d height %d pix_fmt %4.4s", __FUNCTION__,
415 for (
const auto &buf :
buffer) {
416 if (buf->IsDirty() && buf->DmaBufHandle() == primeFd)
426 for (
const auto &buf :
buffer) {
438 for (
const auto &buf :
buffer) {
439 if (buf->IsDirty() && !buf->IsPresentationPending())
448 for (
const auto &buf :
buffer) {
449 if (buf.get() != exceptBuf && buf->
IsDirty()) {
450 av_frame_free(&buf->frame);
458 av_frame_free(&
frame);
cDrmBuffer * FindUninitilized(void)
cDrmBuffer * FindByDmaBufHandle(int)
cDrmBuffer * FindNoPresentationPending(void)
void DestroyAllExcept(cDrmBuffer *)
bool m_dirty
true, if the buffer is dirty (it was written to)
cDrmBuffer(void)
cDrmBuffer constructor
bool m_destroyAfterUse
true, if buffer should be destroyed after use
int m_objIdx[4]
index of the objects
bool m_closeHandleOnDestroy
true, if DMA-BUF handle should be closed on destroy
void Setup(int, uint32_t, uint32_t, uint32_t, AVDRMFrameDescriptor *, bool)
Setup the buffer.
int m_numObjects
number of prime objects in the buffer
uint32_t m_fbId
framebuffer id
virtual ~cDrmBuffer(void)
cDrmBuffer destructor
uint32_t m_width
buffer width
uint32_t m_offset[4]
array of the plane offset
uint32_t m_pitch[4]
array of the plane pitch
void FillBlack(void)
Color the buffer black.
AVFrame * frame
associated AVFrame
uint32_t m_objectPrimeHandle[4]
primedata objects prime handles (count is numObjects, index is objIdx)
int m_dmaBufHandle[4]
DMA-BUF file descriptor.
uint32_t m_pixFmt
buffer pixel format
int m_drmDeviceFd
drm device file descriptor
uint32_t m_height
buffer height
void PresentationFinished(void)
bool m_presentationPending
true, if buffer is pending presentation
uint8_t * m_pPlane[4]
array of the plane data
void Destroy(void)
Clear and destroy the buffer object and its parameters.
uint32_t m_size[4]
array of the plane size
uint32_t m_planePrimeHandle[4]
array of the plane handles
int m_numPlanes
number of planes in the buffer
std::vector< std::unique_ptr< cDrmBuffer > > buffer
const struct format_info * FindFormat(uint32_t format)
Find infos for the given pixel format.
static const struct format_info format_info_array[]
Infos of a pixel format.
Logger class header file.
#define LOGFATAL
Logger macros.