18#include <libavutil/buffer.h>
19#include <libavutil/frame.h>
20#include <libavutil/hwcontext_drm.h>
23#include <Gfx/Graph/interop/DrmFourcc.hpp>
29namespace score::gfx::interop
54inline AVDRMFrameDescriptor* buildDrmDescriptor(
55 const DrmPlaneSpan* blocks,
int nBlocks, uint32_t fourcc,
56 uint64_t modifier,
int width,
int height)
noexcept
58 if(!blocks || nBlocks < 1 || fourcc == 0)
61 auto* desc =
static_cast<AVDRMFrameDescriptor*
>(
62 std::calloc(1,
sizeof(AVDRMFrameDescriptor)));
69 desc->objects[0].fd = blocks[0].fd;
70 desc->objects[0].size = blocks[0].maxsize;
71 desc->objects[0].format_modifier = modifier;
74 desc->layers[0].format = fourcc;
76 const int srcStride = blocks[0].stride;
77 const std::size_t srcOffset = blocks[0].offset;
85 const int pitch = srcStride > 0
87 : (fourcc == DRM_P010 ? width * 2 : width);
88 const std::size_t y_size = std::size_t(pitch) * height;
89 desc->layers[0].nb_planes = 2;
90 desc->layers[0].planes[0].object_index = 0;
91 desc->layers[0].planes[0].offset = srcOffset;
92 desc->layers[0].planes[0].pitch = pitch;
93 desc->layers[0].planes[1].object_index = 0;
94 desc->layers[0].planes[1].offset = srcOffset + y_size;
95 desc->layers[0].planes[1].pitch = pitch;
103 const int yPitch = srcStride > 0 ? srcStride : width;
104 const int uvPitch = yPitch / 2;
105 const std::size_t y_size = std::size_t(yPitch) * height;
106 const std::size_t uv_size = std::size_t(uvPitch) * (height / 2);
107 desc->layers[0].nb_planes = 3;
108 desc->layers[0].planes[0].object_index = 0;
109 desc->layers[0].planes[0].offset = srcOffset;
110 desc->layers[0].planes[0].pitch = yPitch;
111 desc->layers[0].planes[1].object_index = 0;
112 desc->layers[0].planes[1].offset = srcOffset + y_size;
113 desc->layers[0].planes[1].pitch = uvPitch;
114 desc->layers[0].planes[2].object_index = 0;
115 desc->layers[0].planes[2].offset = srcOffset + y_size + uv_size;
116 desc->layers[0].planes[2].pitch = uvPitch;
122 desc->layers[0].nb_planes = 1;
123 desc->layers[0].planes[0].object_index = 0;
124 desc->layers[0].planes[0].offset = srcOffset;
125 desc->layers[0].planes[0].pitch = srcStride;
135 const int n = std::min(nBlocks,
int(AV_DRM_MAX_PLANES));
136 desc->nb_objects = n;
138 desc->layers[0].format = fourcc;
139 desc->layers[0].nb_planes = n;
140 for(
int i = 0; i < n; ++i)
142 desc->objects[i].fd = blocks[i].fd;
143 desc->objects[i].size = blocks[i].maxsize;
144 desc->objects[i].format_modifier = modifier;
145 desc->layers[0].planes[i].object_index = i;
146 desc->layers[0].planes[i].offset = blocks[i].offset;
147 desc->layers[0].planes[i].pitch = blocks[i].stride;
157inline AVFrame* wrapDescriptorAsDrmPrime(
158 AVDRMFrameDescriptor* desc,
int width,
int height,
159 void (*release)(
void*, uint8_t*),
void* opaque)
noexcept
161 AVFrame* f = av_frame_alloc();
167 f->format = AV_PIX_FMT_DRM_PRIME;
170 f->data[0] =
reinterpret_cast<uint8_t*
>(desc);
171 f->buf[0] = av_buffer_create(
172 reinterpret_cast<uint8_t*
>(desc),
sizeof(*desc), release, opaque,
173 AV_BUFFER_FLAG_READONLY);