fixup! lavu/hwcontext_drm: preparations for RKMPP hwcontext

Introduce AVRKMPPDRMFrameDescriptor

This is exactly like AVDRMFrameDescriptor but attionally it holds
MppBuffer instance used on each index. With that, AVDRMObjectDescriptor
can be kept as is, and no need to modify the existing API.
This commit is contained in:
boogie
2024-01-03 23:10:19 +08:00
committed by nyanmisaka
parent 9e7314093f
commit 50cc62684a
4 changed files with 60 additions and 65 deletions
+3 -4
View File
@@ -321,9 +321,9 @@ static int rkmpp_set_buffer_group(AVCodecContext *avctx,
MppBufferInfo buf_info = {
.index = i,
.type = MPP_BUFFER_TYPE_DRM,
.fd = rkmpp_fc->frames[i].objects[0].fd,
.ptr = rkmpp_fc->frames[i].objects[0].ptr,
.size = rkmpp_fc->frames[i].objects[0].size,
.ptr = mpp_buffer_get_ptr(rkmpp_fc->frames[i].buffers[0]),
.fd = rkmpp_fc->frames[i].drm_desc.objects[0].fd,
.size = rkmpp_fc->frames[i].drm_desc.objects[0].size,
};
if ((ret = mpp_buffer_commit(r->buf_group, &buf_info)) != MPP_OK) {
@@ -485,7 +485,6 @@ static int rkmpp_export_frame(AVCodecContext *avctx, AVFrame *frame, MppFrame mp
desc->nb_objects = 1;
desc->objects[0].fd = mpp_buffer_get_fd(mpp_buf);
desc->objects[0].ptr = mpp_buffer_get_ptr(mpp_buf);
desc->objects[0].size = mpp_buffer_get_size(mpp_buf);
mpp_fmt = mpp_frame_get_fmt(mpp_frame);
-10
View File
@@ -50,12 +50,6 @@ typedef struct AVDRMObjectDescriptor {
* DRM PRIME fd for the object.
*/
int fd;
/**
* DRM PRIME mapped virtual ptr for above fd.
*
* The content of this buffer must be readonly when acting decoder's out buffer.
*/
void *ptr;
/**
* Total size of the object.
*
@@ -69,10 +63,6 @@ typedef struct AVDRMObjectDescriptor {
* DRM_FORMAT_MOD_INVALID.
*/
uint64_t format_modifier;
/**
* User opaque for the object.
*/
void *opaque;
} AVDRMObjectDescriptor;
/**
+39 -49
View File
@@ -124,39 +124,27 @@ static int rkmpp_frames_get_constraints(AVHWDeviceContext *hwdev,
return 0;
}
static void rkmpp_free_drm_frame_descriptor(AVRKMPPDeviceContext *hwctx,
AVDRMFrameDescriptor *desc)
static void rkmpp_free_drm_frame_descriptor(void *opaque, uint8_t *data)
{
int i, ret;
MppBuffer mpp_buf = opaque;
AVRKMPPDRMFrameDescriptor *desc = (AVRKMPPDRMFrameDescriptor *)data;
int ret;
if (!desc)
return;
for (i = 0; i < desc->nb_objects; i++) {
AVDRMObjectDescriptor *object = &desc->objects[i];
MppBuffer mpp_buf = (MppBuffer)object->opaque;
if (mpp_buf) {
ret = mpp_buffer_put(mpp_buf);
if (ret != MPP_OK)
av_log(NULL, AV_LOG_WARNING,
"Failed to put MPP buffer: %d\n", ret);
}
if (mpp_buf) {
ret = mpp_buffer_put(mpp_buf);
if (ret != MPP_OK)
av_log(NULL, AV_LOG_WARNING,
"Failed to put MPP buffer: %d\n", ret);
}
memset(desc, 0, sizeof(*desc));
av_free(desc);
}
static void rkmpp_buffer_free(void *opaque, uint8_t *data)
{
AVHWFramesContext *hwfc = opaque;
AVRKMPPDeviceContext *hwctx = hwfc->device_ctx->hwctx;
AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)data;
rkmpp_free_drm_frame_descriptor(hwctx, desc);
}
static int rkmpp_get_aligned_linesize(enum AVPixelFormat pix_fmt, int width, int plane)
{
const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(pix_fmt);
@@ -189,7 +177,7 @@ static AVBufferRef *rkmpp_drm_pool_alloc(void *opaque, size_t size)
AVHWFramesContext *hwfc = opaque;
AVRKMPPFramesContext *avfc = hwfc->hwctx;
AVRKMPPDeviceContext *hwctx = hwfc->device_ctx->hwctx;
AVDRMFrameDescriptor *desc;
AVRKMPPDRMFrameDescriptor *desc;
AVDRMLayerDescriptor *layer;
AVBufferRef *ref;
@@ -210,8 +198,8 @@ static AVBufferRef *rkmpp_drm_pool_alloc(void *opaque, size_t size)
if (!desc)
return NULL;
desc->nb_objects = 1;
desc->nb_layers = 1;
desc->drm_desc.nb_objects = 1;
desc->drm_desc.nb_layers = 1;
ret = mpp_buffer_get(avfc->buf_group, &mpp_buf, mpp_buf_size);
if (ret != MPP_OK || !mpp_buf) {
@@ -219,13 +207,12 @@ static AVBufferRef *rkmpp_drm_pool_alloc(void *opaque, size_t size)
ret = AVERROR(ENOMEM);
goto fail;
}
desc->objects[0].opaque = mpp_buf;
desc->buffers[0] = mpp_buf;
desc->objects[0].fd = mpp_buffer_get_fd(mpp_buf);
desc->objects[0].ptr = mpp_buffer_get_ptr(mpp_buf);
desc->objects[0].size = mpp_buffer_get_size(mpp_buf);
desc->drm_desc.objects[0].fd = mpp_buffer_get_fd(mpp_buf);
desc->drm_desc.objects[0].size = mpp_buffer_get_size(mpp_buf);
layer = &desc->layers[0];
layer = &desc->drm_desc.layers[0];
for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
if (supported_formats[i].pixfmt == hwfc->sw_format) {
layer->format = supported_formats[i].drm_format;
@@ -247,8 +234,8 @@ static AVBufferRef *rkmpp_drm_pool_alloc(void *opaque, size_t size)
rkmpp_get_aligned_linesize(hwfc->sw_format, hwfc->width, i);
}
ref = av_buffer_create((uint8_t*)desc, sizeof(*desc), rkmpp_buffer_free,
opaque, 0);
ref = av_buffer_create((uint8_t*)desc, sizeof(*desc), rkmpp_free_drm_frame_descriptor,
mpp_buf, 0);
if (!ref) {
av_log(hwfc, AV_LOG_ERROR, "Failed to create RKMPP buffer.\n");
goto fail;
@@ -263,7 +250,7 @@ static AVBufferRef *rkmpp_drm_pool_alloc(void *opaque, size_t size)
return ref;
fail:
rkmpp_free_drm_frame_descriptor(hwctx, desc);
rkmpp_free_drm_frame_descriptor(mpp_buf, (uint8_t *)desc);
return NULL;
}
@@ -301,7 +288,7 @@ static int rkmpp_frames_init(AVHWFramesContext *hwfc)
}
hwfc->internal->pool_internal =
av_buffer_pool_init2(sizeof(AVDRMFrameDescriptor), hwfc,
av_buffer_pool_init2(sizeof(AVRKMPPDRMFrameDescriptor), hwfc,
rkmpp_drm_pool_alloc, NULL);
if (!hwfc->internal->pool_internal) {
av_log(hwfc, AV_LOG_ERROR, "Failed to create RKMPP buffer pool.\n");
@@ -371,7 +358,7 @@ static int rkmpp_map_frame(AVHWFramesContext *hwfc,
AVFrame *dst, const AVFrame *src, int flags)
{
AVRKMPPDeviceContext *hwctx = hwfc->device_ctx->hwctx;
const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->data[0];
const AVRKMPPDRMFrameDescriptor *desc = (AVRKMPPDRMFrameDescriptor *)src->data[0];
#if HAVE_LINUX_DMA_BUF_H
struct dma_buf_sync sync_start = { 0 };
#endif
@@ -398,44 +385,47 @@ static int rkmpp_map_frame(AVHWFramesContext *hwfc,
sync_start.flags = DMA_BUF_SYNC_START | map->sync_flags;
#endif
if (desc->objects[0].format_modifier != DRM_FORMAT_MOD_LINEAR) {
if (desc->drm_desc.objects[0].format_modifier != DRM_FORMAT_MOD_LINEAR) {
av_log(hwfc, AV_LOG_ERROR, "Transfer non-linear DRM_PRIME frame is not supported!\n");
return AVERROR(ENOSYS);
}
av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES);
for (i = 0; i < desc->nb_objects; i++) {
if (desc->objects[i].ptr) {
addr = desc->objects[i].ptr;
av_assert0(desc->drm_desc.nb_objects <= AV_DRM_MAX_PLANES);
for (i = 0; i < desc->drm_desc.nb_objects; i++) {
addr = NULL;
if (desc->buffers[i])
addr = mpp_buffer_get_ptr(desc->buffers[i]);
if (addr) {
map->unmap[i] = 0;
} else {
addr = mmap(NULL, desc->objects[i].size, mmap_prot, MAP_SHARED,
desc->objects[i].fd, 0);
addr = mmap(NULL, desc->drm_desc.objects[i].size, mmap_prot, MAP_SHARED,
desc->drm_desc.objects[i].fd, 0);
if (addr == MAP_FAILED) {
err = AVERROR(errno);
av_log(hwfc, AV_LOG_ERROR, "Failed to map RKMPP object %d to "
"memory: %d.\n", desc->objects[i].fd, errno);
"memory: %d.\n", desc->drm_desc.objects[i].fd, errno);
goto fail;
}
map->unmap[i] = 1;
}
map->address[i] = addr;
map->length[i] = desc->objects[i].size;
map->object[i] = desc->objects[i].fd;
map->length[i] = desc->drm_desc.objects[i].size;
map->object[i] = desc->drm_desc.objects[i].fd;
#if HAVE_LINUX_DMA_BUF_H
/* We're not checking for errors here because the kernel may not
* support the ioctl, in which case its okay to carry on */
if (hwctx->flags & MPP_BUFFER_FLAGS_CACHABLE)
ioctl(desc->objects[i].fd, DMA_BUF_IOCTL_SYNC, &sync_start);
ioctl(desc->drm_desc.objects[i].fd, DMA_BUF_IOCTL_SYNC, &sync_start);
#endif
}
map->nb_regions = i;
plane = 0;
for (i = 0; i < desc->nb_layers; i++) {
const AVDRMLayerDescriptor *layer = &desc->layers[i];
for (i = 0; i < desc->drm_desc.nb_layers; i++) {
const AVDRMLayerDescriptor *layer = &desc->drm_desc.layers[i];
for (p = 0; p < layer->nb_planes; p++) {
dst->data[plane] =
(uint8_t*)map->address[layer->planes[p].object_index] +
@@ -457,7 +447,7 @@ static int rkmpp_map_frame(AVHWFramesContext *hwfc,
return 0;
fail:
for (i = 0; i < desc->nb_objects; i++) {
for (i = 0; i < desc->drm_desc.nb_objects; i++) {
if (map->address[i] && map->unmap[i])
munmap(map->address[i], map->length[i]);
}
+18 -2
View File
@@ -56,6 +56,22 @@
((mod >> 52) == (DRM_FORMAT_MOD_ARM_TYPE_AFBC | \
(DRM_FORMAT_MOD_VENDOR_ARM << 4)))
/**
* DRM Prime Frame descriptor for RKMPP HWDevice.
*/
typedef struct AVRKMPPDRMFrameDescriptor {
/**
* Backwards compatibility with AVDRMFrameDescriptor.
*/
AVDRMFrameDescriptor drm_desc;
/**
* References to MppBuffer instances which are used
* on each drm frame index.
*/
MppBuffer buffers[AV_DRM_MAX_PLANES];
} AVRKMPPDRMFrameDescriptor;
/**
* RKMPP-specific data associated with a frame pool.
*
@@ -72,8 +88,8 @@ typedef struct AVRKMPPFramesContext {
* Only valid if AVHWFramesContext.initial_pool_size was positive.
* These are intended to be used as the buffer of RKMPP decoder.
*/
AVDRMFrameDescriptor *frames;
int nb_frames;
AVRKMPPDRMFrameDescriptor *frames;
int nb_frames;
} AVRKMPPFramesContext;
/**