mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
va: allocator: add _set_format() and _get_format()
Since allocators keep an available memory queue to reuse, video format and usage hint are now persistant while allocator's memories are around. This patch adds _set_format() and _get_format() for both VA allocators. _set_format() validates if given format can be used or reused. If no allocated surface previously it creates a dummy one to fetch its offsets and strides. Updated info is returned to callee. GstVaPool uses _set_format() at config to verify the allocator capacity and to get the surfaces offsets and strides, which are going to be used by the video meta. Allocator extracted caps are compared with caps from config and if they have different strides or offsets, force_videometa is set. A new bufferpool method gst_va_pool_requires_video_meta() is added return the value of force_videometa. This value is checked in order to know if decoders need to copy the surface if downstream doesn't announce video meta support. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1667>
This commit is contained in:
parent
482e93b4d8
commit
fbbf9c629a
7 changed files with 287 additions and 250 deletions
|
@ -400,6 +400,9 @@ struct _GstVaDmabufAllocator
|
||||||
GstMemoryMapFunction parent_map;
|
GstMemoryMapFunction parent_map;
|
||||||
|
|
||||||
GCond buffer_cond;
|
GCond buffer_cond;
|
||||||
|
|
||||||
|
GstVideoInfo info;
|
||||||
|
guint usage_hint;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gst_va_dmabuf_allocator_parent_class dmabuf_parent_class
|
#define gst_va_dmabuf_allocator_parent_class dmabuf_parent_class
|
||||||
|
@ -514,11 +517,15 @@ gst_va_dmabuf_memory_release (GstMiniObject * mini_object)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* creates an exported VASurface and adds it as @buffer's memories
|
/* Creates an exported VASurface and adds it as @buffer's memories
|
||||||
* qdata */
|
* qdata
|
||||||
gboolean
|
*
|
||||||
gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
|
* If @info is not NULL, a dummy (non-pooled) buffer is created to
|
||||||
GstBuffer * buffer, GstVaAllocationParams * params)
|
* update offsets and strides, and it has to be unrefed immediately.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
gst_va_dmabuf_allocator_setup_buffer_full (GstAllocator * allocator,
|
||||||
|
GstBuffer * buffer, GstVideoInfo * info)
|
||||||
{
|
{
|
||||||
GstVaBufferSurface *buf;
|
GstVaBufferSurface *buf;
|
||||||
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (allocator);
|
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (allocator);
|
||||||
|
@ -528,20 +535,19 @@ gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
|
||||||
guint32 i, fourcc, rt_format, export_flags;
|
guint32 i, fourcc, rt_format, export_flags;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_VA_DMABUF_ALLOCATOR (allocator), FALSE);
|
g_return_val_if_fail (GST_IS_VA_DMABUF_ALLOCATOR (allocator), FALSE);
|
||||||
g_return_val_if_fail (params, FALSE);
|
|
||||||
|
|
||||||
format = GST_VIDEO_INFO_FORMAT (¶ms->info);
|
format = GST_VIDEO_INFO_FORMAT (&self->info);
|
||||||
fourcc = gst_va_fourcc_from_video_format (format);
|
fourcc = gst_va_fourcc_from_video_format (format);
|
||||||
rt_format = gst_va_chroma_from_video_format (format);
|
rt_format = gst_va_chroma_from_video_format (format);
|
||||||
if (fourcc == 0 || rt_format == 0) {
|
if (fourcc == 0 || rt_format == 0) {
|
||||||
GST_ERROR_OBJECT (allocator, "Unsupported format: %s",
|
GST_ERROR_OBJECT (allocator, "Unsupported format: %s",
|
||||||
gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (¶ms->info)));
|
gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&self->info)));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_create_surfaces (self->display, rt_format, fourcc,
|
if (!_create_surfaces (self->display, rt_format, fourcc,
|
||||||
GST_VIDEO_INFO_WIDTH (¶ms->info),
|
GST_VIDEO_INFO_WIDTH (&self->info),
|
||||||
GST_VIDEO_INFO_HEIGHT (¶ms->info), params->usage_hint, NULL,
|
GST_VIDEO_INFO_HEIGHT (&self->info), self->usage_hint, NULL,
|
||||||
&surface, 1))
|
&surface, 1))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -561,7 +567,7 @@ gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
|
||||||
if (!_export_surface_to_dmabuf (self->display, surface, export_flags, &desc))
|
if (!_export_surface_to_dmabuf (self->display, surface, export_flags, &desc))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
g_assert (GST_VIDEO_INFO_N_PLANES (¶ms->info) == desc.num_layers);
|
g_assert (GST_VIDEO_INFO_N_PLANES (&self->info) == desc.num_layers);
|
||||||
|
|
||||||
if (fourcc != desc.fourcc) {
|
if (fourcc != desc.fourcc) {
|
||||||
GST_ERROR ("Unsupported fourcc: %" GST_FOURCC_FORMAT,
|
GST_ERROR ("Unsupported fourcc: %" GST_FOURCC_FORMAT,
|
||||||
|
@ -570,7 +576,10 @@ gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = gst_va_buffer_surface_new (surface, format, desc.width, desc.height);
|
buf = gst_va_buffer_surface_new (surface, format, desc.width, desc.height);
|
||||||
GST_VIDEO_INFO_SIZE (¶ms->info) = 0;
|
if (G_UNLIKELY (info)) {
|
||||||
|
*info = self->info;
|
||||||
|
GST_VIDEO_INFO_SIZE (info) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < desc.num_objects; i++) {
|
for (i = 0; i < desc.num_objects; i++) {
|
||||||
gint fd = desc.objects[i].fd;
|
gint fd = desc.objects[i].fd;
|
||||||
|
@ -581,7 +590,8 @@ gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
|
||||||
|
|
||||||
gst_buffer_append_memory (buffer, mem);
|
gst_buffer_append_memory (buffer, mem);
|
||||||
|
|
||||||
GST_MINI_OBJECT (mem)->dispose = gst_va_dmabuf_memory_release;
|
if (G_LIKELY (!info))
|
||||||
|
GST_MINI_OBJECT (mem)->dispose = gst_va_dmabuf_memory_release;
|
||||||
|
|
||||||
g_atomic_int_add (&buf->ref_count, 1);
|
g_atomic_int_add (&buf->ref_count, 1);
|
||||||
gst_mini_object_set_qdata (GST_MINI_OBJECT (mem),
|
gst_mini_object_set_qdata (GST_MINI_OBJECT (mem),
|
||||||
|
@ -591,21 +601,23 @@ gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
|
||||||
gst_mini_object_set_qdata (GST_MINI_OBJECT (mem), gst_va_drm_mod_quark (),
|
gst_mini_object_set_qdata (GST_MINI_OBJECT (mem), gst_va_drm_mod_quark (),
|
||||||
drm_mod, g_free);
|
drm_mod, g_free);
|
||||||
|
|
||||||
GST_VIDEO_INFO_SIZE (¶ms->info) += size;
|
if (G_UNLIKELY (info))
|
||||||
|
GST_VIDEO_INFO_SIZE (info) += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < desc.num_layers; i++) {
|
if (G_UNLIKELY (info)) {
|
||||||
g_assert (desc.layers[i].num_planes == 1);
|
for (i = 0; i < desc.num_layers; i++) {
|
||||||
GST_VIDEO_INFO_PLANE_OFFSET (¶ms->info, i) = desc.layers[i].offset[0];
|
g_assert (desc.layers[i].num_planes == 1);
|
||||||
GST_VIDEO_INFO_PLANE_STRIDE (¶ms->info, i) = desc.layers[i].pitch[0];
|
GST_VIDEO_INFO_PLANE_OFFSET (info, i) = desc.layers[i].offset[0];
|
||||||
|
GST_VIDEO_INFO_PLANE_STRIDE (info, i) = desc.layers[i].pitch[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_atomic_int_inc (&self->surface_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_atomic_int_inc (&self->surface_count);
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (self, "Created surface %#x [%dx%d] size %" G_GSIZE_FORMAT,
|
GST_LOG_OBJECT (self, "Created surface %#x [%dx%d] size %" G_GSIZE_FORMAT,
|
||||||
buf->surface, GST_VIDEO_INFO_WIDTH (¶ms->info),
|
buf->surface, GST_VIDEO_INFO_WIDTH (&self->info),
|
||||||
GST_VIDEO_INFO_HEIGHT (¶ms->info),
|
GST_VIDEO_INFO_HEIGHT (&self->info), GST_VIDEO_INFO_SIZE (&self->info));
|
||||||
GST_VIDEO_INFO_SIZE (¶ms->info));
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -616,6 +628,13 @@ failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
|
||||||
|
GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
return gst_va_dmabuf_allocator_setup_buffer_full (allocator, buffer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_va_dmabuf_allocator_prepare_buffer (GstAllocator * allocator,
|
gst_va_dmabuf_allocator_prepare_buffer (GstAllocator * allocator,
|
||||||
GstBuffer * buffer)
|
GstBuffer * buffer)
|
||||||
|
@ -669,27 +688,75 @@ gst_va_dmabuf_allocator_flush (GstAllocator * allocator)
|
||||||
GST_OBJECT_UNLOCK (self);
|
GST_OBJECT_UNLOCK (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
gst_va_dmabuf_try (GstAllocator * allocator, GstVaAllocationParams * params)
|
gst_va_dmabuf_allocator_try (GstAllocator * allocator)
|
||||||
{
|
{
|
||||||
GstBuffer *buffer = gst_buffer_new ();
|
GstBuffer *buffer;
|
||||||
GstMapInfo map_info;
|
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (allocator);
|
||||||
|
GstVideoInfo info = self->info;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
ret = gst_va_dmabuf_allocator_setup_buffer (allocator, buffer, params);
|
buffer = gst_buffer_new ();
|
||||||
if (ret) {
|
ret = gst_va_dmabuf_allocator_setup_buffer_full (allocator, buffer, &info);
|
||||||
/* XXX: radeonsi for kadaveri cannot map dmabufs to user space */
|
|
||||||
if (!gst_buffer_map (buffer, &map_info, GST_MAP_READWRITE)) {
|
|
||||||
GST_WARNING_OBJECT (allocator,
|
|
||||||
"DMABuf backend cannot map frames to user space.");
|
|
||||||
}
|
|
||||||
gst_buffer_unmap (buffer, &map_info);
|
|
||||||
}
|
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
self->info = info;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_va_dmabuf_allocator_set_format (GstAllocator * allocator,
|
||||||
|
GstVideoInfo * info, guint usage_hint)
|
||||||
|
{
|
||||||
|
GstVaDmabufAllocator *self;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_VA_DMABUF_ALLOCATOR (allocator), FALSE);
|
||||||
|
g_return_val_if_fail (info, FALSE);
|
||||||
|
|
||||||
|
self = GST_VA_DMABUF_ALLOCATOR (allocator);
|
||||||
|
|
||||||
|
if (self->surface_count != 0) {
|
||||||
|
if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_INFO_FORMAT (&self->info)
|
||||||
|
&& GST_VIDEO_INFO_WIDTH (info) == GST_VIDEO_INFO_WIDTH (&self->info)
|
||||||
|
&& GST_VIDEO_INFO_HEIGHT (info) == GST_VIDEO_INFO_HEIGHT (&self->info)
|
||||||
|
&& usage_hint == self->usage_hint) {
|
||||||
|
*info = self->info; /* update callee info (offset & stride) */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->usage_hint = usage_hint;
|
||||||
|
self->info = *info;
|
||||||
|
|
||||||
|
ret = gst_va_dmabuf_allocator_try (allocator);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
*info = self->info;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_va_dmabuf_allocator_get_format (GstAllocator * allocator,
|
||||||
|
GstVideoInfo * info, guint * usage_hint)
|
||||||
|
{
|
||||||
|
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (allocator);
|
||||||
|
|
||||||
|
if (GST_VIDEO_INFO_FORMAT (&self->info) == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
*info = self->info;
|
||||||
|
if (usage_hint)
|
||||||
|
*usage_hint = self->usage_hint;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX: use a surface pool to control the created surfaces */
|
/* XXX: use a surface pool to control the created surfaces */
|
||||||
gboolean
|
gboolean
|
||||||
gst_va_dmabuf_memories_setup (GstVaDisplay * display, GstVideoInfo * info,
|
gst_va_dmabuf_memories_setup (GstVaDisplay * display, GstVideoInfo * info,
|
||||||
|
@ -773,6 +840,9 @@ struct _GstVaAllocator
|
||||||
GArray *surface_formats;
|
GArray *surface_formats;
|
||||||
|
|
||||||
GCond buffer_cond;
|
GCond buffer_cond;
|
||||||
|
|
||||||
|
GstVideoInfo info;
|
||||||
|
guint usage_hint;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _GstVaMemory GstVaMemory;
|
typedef struct _GstVaMemory GstVaMemory;
|
||||||
|
@ -780,7 +850,6 @@ struct _GstVaMemory
|
||||||
{
|
{
|
||||||
GstMemory mem;
|
GstMemory mem;
|
||||||
|
|
||||||
GstVideoInfo info;
|
|
||||||
VASurfaceID surface;
|
VASurfaceID surface;
|
||||||
GstVideoFormat surface_format;
|
GstVideoFormat surface_format;
|
||||||
VAImage image;
|
VAImage image;
|
||||||
|
@ -886,7 +955,7 @@ _reset_mem (GstVaMemory * mem, GstAllocator * allocator, gsize size)
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
_ensure_image (GstVaDisplay * display, VASurfaceID surface, GstVideoInfo * info,
|
_ensure_image (GstVaDisplay * display, VASurfaceID surface, GstVideoInfo * info,
|
||||||
VAImage * image, gboolean * derived)
|
VAImage * image, gboolean * derived, gboolean update_info)
|
||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
gboolean try_derived;
|
gboolean try_derived;
|
||||||
|
@ -909,12 +978,14 @@ _ensure_image (GstVaDisplay * display, VASurfaceID surface, GstVideoInfo * info,
|
||||||
*derived = FALSE;
|
*derived = FALSE;
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
for (i = 0; i < image->num_planes; i++) {
|
if (G_UNLIKELY (update_info)) {
|
||||||
GST_VIDEO_INFO_PLANE_OFFSET (info, i) = image->offsets[i];
|
for (i = 0; i < image->num_planes; i++) {
|
||||||
GST_VIDEO_INFO_PLANE_STRIDE (info, i) = image->pitches[i];
|
GST_VIDEO_INFO_PLANE_OFFSET (info, i) = image->offsets[i];
|
||||||
}
|
GST_VIDEO_INFO_PLANE_STRIDE (info, i) = image->pitches[i];
|
||||||
|
}
|
||||||
|
|
||||||
GST_VIDEO_INFO_SIZE (info) = image->data_size;
|
GST_VIDEO_INFO_SIZE (info) = image->data_size;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -945,7 +1016,7 @@ _va_map_unlocked (GstVaMemory * mem, GstMapFlags flags)
|
||||||
} else { /* GST_MAP_READ only */
|
} else { /* GST_MAP_READ only */
|
||||||
mem->is_dirty = FALSE;
|
mem->is_dirty = FALSE;
|
||||||
mem->is_derived = va_allocator->use_derived &&
|
mem->is_derived = va_allocator->use_derived &&
|
||||||
(GST_VIDEO_INFO_FORMAT (&mem->info) == mem->surface_format);
|
(GST_VIDEO_INFO_FORMAT (&va_allocator->info) == mem->surface_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & GST_MAP_VA) {
|
if (flags & GST_MAP_VA) {
|
||||||
|
@ -953,8 +1024,8 @@ _va_map_unlocked (GstVaMemory * mem, GstMapFlags flags)
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_ensure_image (display, mem->surface, &mem->info, &mem->image,
|
if (!_ensure_image (display, mem->surface, &va_allocator->info, &mem->image,
|
||||||
&mem->is_derived))
|
&mem->is_derived, FALSE))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
va_allocator->use_derived = mem->is_derived;
|
va_allocator->use_derived = mem->is_derived;
|
||||||
|
@ -1063,7 +1134,6 @@ _va_share (GstMemory * mem, gssize offset, gssize size)
|
||||||
|
|
||||||
sub->surface = vamem->surface;
|
sub->surface = vamem->surface;
|
||||||
sub->surface_format = vamem->surface_format;
|
sub->surface_format = vamem->surface_format;
|
||||||
sub->info = vamem->info;
|
|
||||||
|
|
||||||
_clean_mem (sub);
|
_clean_mem (sub);
|
||||||
|
|
||||||
|
@ -1110,14 +1180,16 @@ gst_va_memory_release (GstMiniObject * mini_object)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstMemory *
|
/* If @info is not NULL, a dummy (non-pooled) memory and its VAImage
|
||||||
gst_va_allocator_alloc (GstAllocator * allocator,
|
* are created, to update offsets and strides. The memory has to be
|
||||||
GstVaAllocationParams * params)
|
* unrefed immediately.
|
||||||
|
*/
|
||||||
|
static GstMemory *
|
||||||
|
gst_va_allocator_alloc_full (GstAllocator * allocator, GstVideoInfo * info)
|
||||||
{
|
{
|
||||||
GstVaAllocator *self;
|
GstVaAllocator *self;
|
||||||
GstVaMemory *mem;
|
GstVaMemory *mem;
|
||||||
GstVideoFormat format, img_format;
|
GstVideoFormat format, img_format;
|
||||||
VAImage image = { 0, };
|
|
||||||
VASurfaceID surface;
|
VASurfaceID surface;
|
||||||
guint32 fourcc, rt_format;
|
guint32 fourcc, rt_format;
|
||||||
|
|
||||||
|
@ -1125,7 +1197,7 @@ gst_va_allocator_alloc (GstAllocator * allocator,
|
||||||
|
|
||||||
self = GST_VA_ALLOCATOR (allocator);
|
self = GST_VA_ALLOCATOR (allocator);
|
||||||
|
|
||||||
img_format = GST_VIDEO_INFO_FORMAT (¶ms->info);
|
img_format = GST_VIDEO_INFO_FORMAT (&self->info);
|
||||||
|
|
||||||
format = gst_va_video_surface_format_from_image_format (img_format,
|
format = gst_va_video_surface_format_from_image_format (img_format,
|
||||||
self->surface_formats);
|
self->surface_formats);
|
||||||
|
@ -1145,35 +1217,43 @@ gst_va_allocator_alloc (GstAllocator * allocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_create_surfaces (self->display, rt_format, fourcc,
|
if (!_create_surfaces (self->display, rt_format, fourcc,
|
||||||
GST_VIDEO_INFO_WIDTH (¶ms->info),
|
GST_VIDEO_INFO_WIDTH (&self->info),
|
||||||
GST_VIDEO_INFO_HEIGHT (¶ms->info), params->usage_hint, NULL,
|
GST_VIDEO_INFO_HEIGHT (&self->info), self->usage_hint, NULL,
|
||||||
&surface, 1))
|
&surface, 1))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
image.image_id = VA_INVALID_ID;
|
if (G_UNLIKELY (info)) {
|
||||||
if (!_ensure_image (self->display, surface, ¶ms->info, &image, NULL))
|
VAImage image = {.image_id = VA_INVALID_ID, };
|
||||||
return NULL;
|
|
||||||
_destroy_image (self->display, image.image_id);
|
if (!_ensure_image (self->display, surface, info, &image, NULL, TRUE))
|
||||||
|
return NULL;
|
||||||
|
_destroy_image (self->display, image.image_id);
|
||||||
|
}
|
||||||
|
|
||||||
mem = g_slice_new (GstVaMemory);
|
mem = g_slice_new (GstVaMemory);
|
||||||
|
|
||||||
mem->surface = surface;
|
mem->surface = surface;
|
||||||
mem->surface_format = format;
|
mem->surface_format = format;
|
||||||
mem->info = params->info;
|
|
||||||
|
|
||||||
_reset_mem (mem, allocator, GST_VIDEO_INFO_SIZE (¶ms->info));
|
_reset_mem (mem, allocator, GST_VIDEO_INFO_SIZE (&self->info));
|
||||||
|
|
||||||
GST_MINI_OBJECT (mem)->dispose = gst_va_memory_release;
|
if (G_LIKELY (!info)) {
|
||||||
|
GST_MINI_OBJECT (mem)->dispose = gst_va_memory_release;
|
||||||
g_atomic_int_inc (&self->surface_count);
|
g_atomic_int_inc (&self->surface_count);
|
||||||
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (self, "Created surface %#x [%dx%d]", mem->surface,
|
GST_LOG_OBJECT (self, "Created surface %#x [%dx%d]", mem->surface,
|
||||||
GST_VIDEO_INFO_WIDTH (¶ms->info),
|
GST_VIDEO_INFO_WIDTH (&self->info), GST_VIDEO_INFO_HEIGHT (&self->info));
|
||||||
GST_VIDEO_INFO_HEIGHT (¶ms->info));
|
|
||||||
|
|
||||||
return GST_MEMORY_CAST (mem);
|
return GST_MEMORY_CAST (mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GstMemory *
|
||||||
|
gst_va_allocator_alloc (GstAllocator * allocator)
|
||||||
|
{
|
||||||
|
return gst_va_allocator_alloc_full (allocator, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
GstAllocator *
|
GstAllocator *
|
||||||
gst_va_allocator_new (GstVaDisplay * display, GArray * surface_formats)
|
gst_va_allocator_new (GstVaDisplay * display, GArray * surface_formats)
|
||||||
{
|
{
|
||||||
|
@ -1224,15 +1304,69 @@ gst_va_allocator_flush (GstAllocator * allocator)
|
||||||
GST_OBJECT_UNLOCK (self);
|
GST_OBJECT_UNLOCK (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
gst_va_allocator_try (GstAllocator * allocator, GstVaAllocationParams * params)
|
gst_va_allocator_try (GstAllocator * allocator)
|
||||||
{
|
{
|
||||||
GstMemory *mem;
|
GstMemory *mem;
|
||||||
|
GstVaAllocator *self = GST_VA_ALLOCATOR (allocator);
|
||||||
|
GstVideoInfo info = self->info;
|
||||||
|
|
||||||
mem = gst_va_allocator_alloc (allocator, params);
|
mem = gst_va_allocator_alloc_full (allocator, &info);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
gst_memory_unref (mem);
|
gst_memory_unref (mem);
|
||||||
|
|
||||||
|
self->info = info;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_va_allocator_set_format (GstAllocator * allocator, GstVideoInfo * info,
|
||||||
|
guint usage_hint)
|
||||||
|
{
|
||||||
|
GstVaAllocator *self;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_VA_ALLOCATOR (allocator), FALSE);
|
||||||
|
g_return_val_if_fail (info, FALSE);
|
||||||
|
|
||||||
|
self = GST_VA_ALLOCATOR (allocator);
|
||||||
|
|
||||||
|
if (self->surface_count != 0) {
|
||||||
|
if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_INFO_FORMAT (&self->info)
|
||||||
|
&& GST_VIDEO_INFO_WIDTH (info) == GST_VIDEO_INFO_WIDTH (&self->info)
|
||||||
|
&& GST_VIDEO_INFO_HEIGHT (info) == GST_VIDEO_INFO_HEIGHT (&self->info)
|
||||||
|
&& usage_hint == self->usage_hint) {
|
||||||
|
*info = self->info; /* update callee info (offset & stride) */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->usage_hint = usage_hint;
|
||||||
|
self->info = *info;
|
||||||
|
|
||||||
|
ret = gst_va_allocator_try (allocator);
|
||||||
|
if (ret)
|
||||||
|
*info = self->info;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_va_allocator_get_format (GstAllocator * allocator, GstVideoInfo * info,
|
||||||
|
guint * usage_hint)
|
||||||
|
{
|
||||||
|
GstVaAllocator *self = GST_VA_ALLOCATOR (allocator);
|
||||||
|
|
||||||
|
if (GST_VIDEO_INFO_FORMAT (&self->info) == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
*info = self->info;
|
||||||
|
if (usage_hint)
|
||||||
|
*usage_hint = self->usage_hint;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,26 +27,22 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GstVaAllocationParams GstVaAllocationParams;
|
|
||||||
struct _GstVaAllocationParams
|
|
||||||
{
|
|
||||||
GstVideoInfo info;
|
|
||||||
guint32 usage_hint;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GST_TYPE_VA_DMABUF_ALLOCATOR (gst_va_dmabuf_allocator_get_type())
|
#define GST_TYPE_VA_DMABUF_ALLOCATOR (gst_va_dmabuf_allocator_get_type())
|
||||||
G_DECLARE_FINAL_TYPE (GstVaDmabufAllocator, gst_va_dmabuf_allocator, GST,
|
G_DECLARE_FINAL_TYPE (GstVaDmabufAllocator, gst_va_dmabuf_allocator, GST,
|
||||||
VA_DMABUF_ALLOCATOR, GstDmaBufAllocator);
|
VA_DMABUF_ALLOCATOR, GstDmaBufAllocator);
|
||||||
|
|
||||||
GstAllocator * gst_va_dmabuf_allocator_new (GstVaDisplay * display);
|
GstAllocator * gst_va_dmabuf_allocator_new (GstVaDisplay * display);
|
||||||
gboolean gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
|
gboolean gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
|
||||||
GstBuffer * buffer,
|
GstBuffer * buffer);
|
||||||
GstVaAllocationParams * params);
|
|
||||||
gboolean gst_va_dmabuf_allocator_prepare_buffer (GstAllocator * allocator,
|
gboolean gst_va_dmabuf_allocator_prepare_buffer (GstAllocator * allocator,
|
||||||
GstBuffer * buffer);
|
GstBuffer * buffer);
|
||||||
void gst_va_dmabuf_allocator_flush (GstAllocator * allocator);
|
void gst_va_dmabuf_allocator_flush (GstAllocator * allocator);
|
||||||
gboolean gst_va_dmabuf_try (GstAllocator * allocator,
|
gboolean gst_va_dmabuf_allocator_set_format (GstAllocator * allocator,
|
||||||
GstVaAllocationParams * params);
|
GstVideoInfo * info,
|
||||||
|
guint usage_hint);
|
||||||
|
gboolean gst_va_dmabuf_allocator_get_format (GstAllocator * allocator,
|
||||||
|
GstVideoInfo * info,
|
||||||
|
guint * usage_hint);
|
||||||
|
|
||||||
gboolean gst_va_dmabuf_memories_setup (GstVaDisplay * display,
|
gboolean gst_va_dmabuf_memories_setup (GstVaDisplay * display,
|
||||||
GstVideoInfo * info,
|
GstVideoInfo * info,
|
||||||
|
@ -65,13 +61,16 @@ G_DECLARE_FINAL_TYPE (GstVaAllocator, gst_va_allocator, GST, VA_ALLOCATOR, GstAl
|
||||||
|
|
||||||
GstAllocator * gst_va_allocator_new (GstVaDisplay * display,
|
GstAllocator * gst_va_allocator_new (GstVaDisplay * display,
|
||||||
GArray * surface_formats);
|
GArray * surface_formats);
|
||||||
GstMemory * gst_va_allocator_alloc (GstAllocator * allocator,
|
GstMemory * gst_va_allocator_alloc (GstAllocator * allocator);
|
||||||
GstVaAllocationParams * params);
|
|
||||||
gboolean gst_va_allocator_prepare_buffer (GstAllocator * allocator,
|
gboolean gst_va_allocator_prepare_buffer (GstAllocator * allocator,
|
||||||
GstBuffer * buffer);
|
GstBuffer * buffer);
|
||||||
void gst_va_allocator_flush (GstAllocator * allocator);
|
void gst_va_allocator_flush (GstAllocator * allocator);
|
||||||
gboolean gst_va_allocator_try (GstAllocator * allocator,
|
gboolean gst_va_allocator_set_format (GstAllocator * allocator,
|
||||||
GstVaAllocationParams * params);
|
GstVideoInfo * info,
|
||||||
|
guint usage_hint);
|
||||||
|
gboolean gst_va_allocator_get_format (GstAllocator * allocator,
|
||||||
|
GstVideoInfo * info,
|
||||||
|
guint * usage_hint);
|
||||||
|
|
||||||
VASurfaceID gst_va_memory_get_surface (GstMemory * mem);
|
VASurfaceID gst_va_memory_get_surface (GstMemory * mem);
|
||||||
VASurfaceID gst_va_buffer_get_surface (GstBuffer * buffer);
|
VASurfaceID gst_va_buffer_get_surface (GstBuffer * buffer);
|
||||||
|
|
|
@ -745,6 +745,17 @@ gst_va_h264_dec_new_sequence (GstH264Decoder * decoder, const GstH264SPS * sps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!self->has_videometa) {
|
||||||
|
GstBufferPool *pool;
|
||||||
|
|
||||||
|
pool = gst_video_decoder_get_buffer_pool (GST_VIDEO_DECODER (self));
|
||||||
|
self->copy_frames = gst_va_pool_requires_video_meta (pool);
|
||||||
|
gst_object_unref (pool);
|
||||||
|
|
||||||
|
if (self->copy_frames)
|
||||||
|
GST_INFO_OBJECT (self, "Raw frame copy enabled.");
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1048,81 +1059,19 @@ gst_va_h264_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
_shall_copy_frames (GstVaH264Dec * self, GstVideoInfo * info)
|
|
||||||
{
|
|
||||||
GstVideoInfo ref_info;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
self->copy_frames = FALSE;
|
|
||||||
|
|
||||||
if (self->has_videometa)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gst_video_info_set_format (&ref_info, GST_VIDEO_INFO_FORMAT (info),
|
|
||||||
self->display_width, self->display_height);
|
|
||||||
|
|
||||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
|
|
||||||
if (info->stride[i] != ref_info.stride[i] ||
|
|
||||||
info->offset[i] != ref_info.offset[i]) {
|
|
||||||
GST_WARNING_OBJECT (self,
|
|
||||||
"GstVideoMeta support required, copying frames.");
|
|
||||||
self->copy_frames = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_try_allocator (GstVaH264Dec * self, GstAllocator * allocator, GstCaps * caps)
|
|
||||||
{
|
|
||||||
GstVaAllocationParams params = {
|
|
||||||
.usage_hint = VA_SURFACE_ATTRIB_USAGE_HINT_DECODER,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!gst_video_info_from_caps (¶ms.info, caps))
|
|
||||||
return FALSE;
|
|
||||||
if (self->need_cropping) {
|
|
||||||
GST_VIDEO_INFO_WIDTH (¶ms.info) = self->coded_width;
|
|
||||||
GST_VIDEO_INFO_HEIGHT (¶ms.info) = self->coded_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GST_IS_VA_DMABUF_ALLOCATOR (allocator)) {
|
|
||||||
if (!gst_va_dmabuf_try (allocator, ¶ms))
|
|
||||||
return FALSE;
|
|
||||||
} else if (GST_IS_VA_ALLOCATOR (allocator)) {
|
|
||||||
if (!gst_va_allocator_try (allocator, ¶ms))
|
|
||||||
return FALSE;
|
|
||||||
if (!gst_caps_is_vamemory (caps))
|
|
||||||
_shall_copy_frames (self, ¶ms.info);
|
|
||||||
} else {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstAllocator *
|
static GstAllocator *
|
||||||
_create_allocator (GstVaH264Dec * self, GstCaps * caps)
|
_create_allocator (GstVaH264Dec * self, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstAllocator *allocator = NULL;
|
GstAllocator *allocator = NULL;
|
||||||
GstVaDisplay *display = NULL;
|
|
||||||
|
|
||||||
g_object_get (self->decoder, "display", &display, NULL);
|
|
||||||
|
|
||||||
if (gst_caps_is_dmabuf (caps))
|
if (gst_caps_is_dmabuf (caps))
|
||||||
allocator = gst_va_dmabuf_allocator_new (display);
|
allocator = gst_va_dmabuf_allocator_new (self->display);
|
||||||
else {
|
else {
|
||||||
GArray *surface_formats =
|
GArray *surface_formats =
|
||||||
gst_va_decoder_get_surface_formats (self->decoder);
|
gst_va_decoder_get_surface_formats (self->decoder);
|
||||||
allocator = gst_va_allocator_new (display, surface_formats);
|
allocator = gst_va_allocator_new (self->display, surface_formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_object_unref (display);
|
|
||||||
|
|
||||||
if (!_try_allocator (self, allocator, caps))
|
|
||||||
gst_clear_object (&allocator);
|
|
||||||
|
|
||||||
return allocator;
|
return allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "gstvapool.h"
|
#include "gstvapool.h"
|
||||||
|
|
||||||
#include "gstvaallocator.h"
|
#include "gstvaallocator.h"
|
||||||
|
#include "gstvacaps.h"
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_va_pool_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_va_pool_debug);
|
||||||
#define GST_CAT_DEFAULT gst_va_pool_debug
|
#define GST_CAT_DEFAULT gst_va_pool_debug
|
||||||
|
@ -36,7 +37,7 @@ struct _GstVaPool
|
||||||
GstVideoInfo alloc_info;
|
GstVideoInfo alloc_info;
|
||||||
GstVideoInfo caps_info;
|
GstVideoInfo caps_info;
|
||||||
GstAllocator *allocator;
|
GstAllocator *allocator;
|
||||||
guint32 usage_hint;
|
gboolean force_videometa;
|
||||||
gboolean add_videometa;
|
gboolean add_videometa;
|
||||||
gboolean need_alignment;
|
gboolean need_alignment;
|
||||||
GstVideoAlignment video_align;
|
GstVideoAlignment video_align;
|
||||||
|
@ -74,9 +75,9 @@ gst_va_pool_set_config (GstBufferPool * pool, GstStructure * config)
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstVaPool *vpool = GST_VA_POOL (pool);
|
GstVaPool *vpool = GST_VA_POOL (pool);
|
||||||
GstVideoAlignment video_align = { 0, };
|
GstVideoAlignment video_align = { 0, };
|
||||||
GstVideoInfo caps_info, alloc_info;
|
GstVideoInfo caps_info, alloc_info, orig_info;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
guint min_buffers, max_buffers;
|
guint i, min_buffers, max_buffers;
|
||||||
guint32 usage_hint;
|
guint32 usage_hint;
|
||||||
|
|
||||||
if (!gst_buffer_pool_config_get_params (config, &caps, NULL, &min_buffers,
|
if (!gst_buffer_pool_config_get_params (config, &caps, NULL, &min_buffers,
|
||||||
|
@ -99,14 +100,12 @@ gst_va_pool_set_config (GstBufferPool * pool, GstStructure * config)
|
||||||
if (!gst_buffer_pool_config_get_va_allocation_params (config, &usage_hint))
|
if (!gst_buffer_pool_config_get_va_allocation_params (config, &usage_hint))
|
||||||
goto wrong_config;
|
goto wrong_config;
|
||||||
|
|
||||||
|
orig_info = caps_info;
|
||||||
width = GST_VIDEO_INFO_WIDTH (&caps_info);
|
width = GST_VIDEO_INFO_WIDTH (&caps_info);
|
||||||
height = GST_VIDEO_INFO_HEIGHT (&caps_info);
|
height = GST_VIDEO_INFO_HEIGHT (&caps_info);
|
||||||
|
|
||||||
GST_LOG_OBJECT (vpool, "%dx%d | %" GST_PTR_FORMAT, width, height, caps);
|
GST_LOG_OBJECT (vpool, "%dx%d | %" GST_PTR_FORMAT, width, height, caps);
|
||||||
|
|
||||||
gst_object_replace ((GstObject **) & vpool->allocator,
|
|
||||||
GST_OBJECT (allocator));
|
|
||||||
|
|
||||||
/* enable metadata based on config of the pool */
|
/* enable metadata based on config of the pool */
|
||||||
vpool->add_videometa = gst_buffer_pool_config_has_option (config,
|
vpool->add_videometa = gst_buffer_pool_config_has_option (config,
|
||||||
GST_BUFFER_POOL_OPTION_VIDEO_META);
|
GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||||
|
@ -128,15 +127,40 @@ gst_va_pool_set_config (GstBufferPool * pool, GstStructure * config)
|
||||||
gst_buffer_pool_config_set_video_alignment (config, &video_align);
|
gst_buffer_pool_config_set_video_alignment (config, &video_align);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* update allocation info with aligned size */
|
||||||
alloc_info = caps_info;
|
alloc_info = caps_info;
|
||||||
GST_VIDEO_INFO_WIDTH (&alloc_info) = width;
|
GST_VIDEO_INFO_WIDTH (&alloc_info) = width;
|
||||||
GST_VIDEO_INFO_HEIGHT (&alloc_info) = height;
|
GST_VIDEO_INFO_HEIGHT (&alloc_info) = height;
|
||||||
|
|
||||||
|
if (GST_IS_VA_DMABUF_ALLOCATOR (allocator)) {
|
||||||
|
if (!gst_va_dmabuf_allocator_set_format (allocator, &alloc_info,
|
||||||
|
usage_hint))
|
||||||
|
goto failed_allocator;
|
||||||
|
} else if (GST_IS_VA_ALLOCATOR (allocator)) {
|
||||||
|
if (!gst_va_allocator_set_format (allocator, &alloc_info, usage_hint))
|
||||||
|
goto failed_allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_object_replace ((GstObject **) & vpool->allocator,
|
||||||
|
GST_OBJECT (allocator));
|
||||||
|
|
||||||
vpool->caps_info = caps_info;
|
vpool->caps_info = caps_info;
|
||||||
vpool->alloc_info = alloc_info;
|
vpool->alloc_info = alloc_info;
|
||||||
vpool->usage_hint = usage_hint;
|
|
||||||
vpool->video_align = video_align;
|
vpool->video_align = video_align;
|
||||||
|
|
||||||
|
if (gst_caps_is_raw (caps)) {
|
||||||
|
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&caps_info); i++) {
|
||||||
|
if (GST_VIDEO_INFO_PLANE_STRIDE (&orig_info, i) !=
|
||||||
|
GST_VIDEO_INFO_PLANE_STRIDE (&alloc_info, i) ||
|
||||||
|
GST_VIDEO_INFO_PLANE_OFFSET (&orig_info, i) !=
|
||||||
|
GST_VIDEO_INFO_PLANE_OFFSET (&alloc_info, i)) {
|
||||||
|
GST_INFO_OBJECT (vpool, "Video meta is required in buffer.");
|
||||||
|
vpool->force_videometa = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* with pooled allocators bufferpool->release_buffer() is cheated
|
/* with pooled allocators bufferpool->release_buffer() is cheated
|
||||||
* because the memories are removed from the buffer at
|
* because the memories are removed from the buffer at
|
||||||
* reset_buffer(), then buffer is an empty holder with size 0 while
|
* reset_buffer(), then buffer is an empty holder with size 0 while
|
||||||
|
@ -167,6 +191,11 @@ failed_to_align:
|
||||||
GST_WARNING_OBJECT (vpool, "Failed to align");
|
GST_WARNING_OBJECT (vpool, "Failed to align");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
failed_allocator:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (vpool, "Failed to set format to allocator");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -176,19 +205,14 @@ gst_va_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
GstVideoMeta *vmeta;
|
GstVideoMeta *vmeta;
|
||||||
GstVaPool *vpool = GST_VA_POOL (pool);
|
GstVaPool *vpool = GST_VA_POOL (pool);
|
||||||
GstVaAllocationParams alloc_params = {
|
|
||||||
.info = vpool->alloc_info,
|
|
||||||
.usage_hint = vpool->usage_hint,
|
|
||||||
};
|
|
||||||
|
|
||||||
buf = gst_buffer_new ();
|
buf = gst_buffer_new ();
|
||||||
|
|
||||||
if (GST_IS_VA_DMABUF_ALLOCATOR (vpool->allocator)) {
|
if (GST_IS_VA_DMABUF_ALLOCATOR (vpool->allocator)) {
|
||||||
if (!gst_va_dmabuf_allocator_setup_buffer (vpool->allocator, buf,
|
if (!gst_va_dmabuf_allocator_setup_buffer (vpool->allocator, buf))
|
||||||
&alloc_params))
|
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
} else if (GST_IS_VA_ALLOCATOR (vpool->allocator)) {
|
} else if (GST_IS_VA_ALLOCATOR (vpool->allocator)) {
|
||||||
GstMemory *mem = gst_va_allocator_alloc (vpool->allocator, &alloc_params);
|
GstMemory *mem = gst_va_allocator_alloc (vpool->allocator);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
gst_buffer_append_memory (buf, mem);
|
gst_buffer_append_memory (buf, mem);
|
||||||
|
@ -203,7 +227,7 @@ gst_va_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
|
||||||
GST_VIDEO_INFO_WIDTH (&vpool->caps_info),
|
GST_VIDEO_INFO_WIDTH (&vpool->caps_info),
|
||||||
GST_VIDEO_INFO_HEIGHT (&vpool->caps_info),
|
GST_VIDEO_INFO_HEIGHT (&vpool->caps_info),
|
||||||
GST_VIDEO_INFO_N_PLANES (&vpool->caps_info),
|
GST_VIDEO_INFO_N_PLANES (&vpool->caps_info),
|
||||||
alloc_params.info.offset, alloc_params.info.stride);
|
vpool->alloc_info.offset, vpool->alloc_info.stride);
|
||||||
|
|
||||||
if (vpool->need_alignment)
|
if (vpool->need_alignment)
|
||||||
gst_video_meta_set_alignment (vmeta, vpool->video_align);
|
gst_video_meta_set_alignment (vmeta, vpool->video_align);
|
||||||
|
@ -342,3 +366,9 @@ gst_buffer_pool_config_set_va_allocation_params (GstStructure * config,
|
||||||
{
|
{
|
||||||
gst_structure_set (config, "usage-hint", G_TYPE_UINT, usage_hint, NULL);
|
gst_structure_set (config, "usage-hint", G_TYPE_UINT, usage_hint, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_va_pool_requires_video_meta (GstBufferPool * pool)
|
||||||
|
{
|
||||||
|
return GST_VA_POOL (pool)->force_videometa;
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ G_BEGIN_DECLS
|
||||||
G_DECLARE_FINAL_TYPE (GstVaPool, gst_va_pool, GST, VA_POOL, GstBufferPool)
|
G_DECLARE_FINAL_TYPE (GstVaPool, gst_va_pool, GST, VA_POOL, GstBufferPool)
|
||||||
|
|
||||||
GstBufferPool * gst_va_pool_new (void);
|
GstBufferPool * gst_va_pool_new (void);
|
||||||
|
gboolean gst_va_pool_requires_video_meta (GstBufferPool * pool);
|
||||||
void gst_buffer_pool_config_set_va_allocation_params (GstStructure * config,
|
void gst_buffer_pool_config_set_va_allocation_params (GstStructure * config,
|
||||||
guint usage_hint);
|
guint usage_hint);
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -367,77 +367,19 @@ gst_va_vp8_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
_shall_copy_frames (GstVaVp8Dec * self, GstVideoInfo * info)
|
|
||||||
{
|
|
||||||
GstVideoInfo ref_info;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
self->copy_frames = FALSE;
|
|
||||||
|
|
||||||
if (self->has_videometa)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gst_video_info_set_format (&ref_info, GST_VIDEO_INFO_FORMAT (info),
|
|
||||||
self->width, self->height);
|
|
||||||
|
|
||||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
|
|
||||||
if (info->stride[i] != ref_info.stride[i] ||
|
|
||||||
info->offset[i] != ref_info.offset[i]) {
|
|
||||||
GST_WARNING_OBJECT (self,
|
|
||||||
"GstVideoMeta support required, copying frames.");
|
|
||||||
self->copy_frames = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_try_allocator (GstVaVp8Dec * self, GstAllocator * allocator, GstCaps * caps)
|
|
||||||
{
|
|
||||||
GstVaAllocationParams params = {
|
|
||||||
.usage_hint = VA_SURFACE_ATTRIB_USAGE_HINT_DECODER,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!gst_video_info_from_caps (¶ms.info, caps))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (GST_IS_VA_DMABUF_ALLOCATOR (allocator)) {
|
|
||||||
if (!gst_va_dmabuf_try (allocator, ¶ms))
|
|
||||||
return FALSE;
|
|
||||||
} else if (GST_IS_VA_ALLOCATOR (allocator)) {
|
|
||||||
if (!gst_va_allocator_try (allocator, ¶ms))
|
|
||||||
return FALSE;
|
|
||||||
if (!gst_caps_is_vamemory (caps))
|
|
||||||
_shall_copy_frames (self, ¶ms.info);
|
|
||||||
} else {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstAllocator *
|
static GstAllocator *
|
||||||
_create_allocator (GstVaVp8Dec * self, GstCaps * caps)
|
_create_allocator (GstVaVp8Dec * self, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstAllocator *allocator = NULL;
|
GstAllocator *allocator = NULL;
|
||||||
GstVaDisplay *display = NULL;
|
|
||||||
|
|
||||||
g_object_get (self->decoder, "display", &display, NULL);
|
if (gst_caps_is_dmabuf (caps)) {
|
||||||
|
allocator = gst_va_dmabuf_allocator_new (self->display);
|
||||||
if (gst_caps_is_dmabuf (caps))
|
} else {
|
||||||
allocator = gst_va_dmabuf_allocator_new (display);
|
|
||||||
else {
|
|
||||||
GArray *surface_formats =
|
GArray *surface_formats =
|
||||||
gst_va_decoder_get_surface_formats (self->decoder);
|
gst_va_decoder_get_surface_formats (self->decoder);
|
||||||
allocator = gst_va_allocator_new (display, surface_formats);
|
allocator = gst_va_allocator_new (self->display, surface_formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_object_unref (display);
|
|
||||||
|
|
||||||
if (!_try_allocator (self, allocator, caps))
|
|
||||||
gst_clear_object (&allocator);
|
|
||||||
|
|
||||||
return allocator;
|
return allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,6 +599,14 @@ gst_va_vp8_dec_new_sequence (GstVp8Decoder * decoder,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!self->has_videometa) {
|
||||||
|
GstBufferPool *pool;
|
||||||
|
|
||||||
|
pool = gst_video_decoder_get_buffer_pool (GST_VIDEO_DECODER (self));
|
||||||
|
self->copy_frames = gst_va_pool_requires_video_meta (pool);
|
||||||
|
gst_object_unref (pool);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -395,29 +395,6 @@ gst_va_vpp_set_context (GstElement * element, GstContext * context)
|
||||||
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
|
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_try_allocator (GstVaVpp * self, GstAllocator * allocator, GstCaps * caps,
|
|
||||||
guint usage_hint)
|
|
||||||
{
|
|
||||||
GstVaAllocationParams params = {
|
|
||||||
.usage_hint = usage_hint,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!gst_video_info_from_caps (¶ms.info, caps))
|
|
||||||
return FALSE;
|
|
||||||
if (GST_IS_VA_DMABUF_ALLOCATOR (allocator)) {
|
|
||||||
if (!gst_va_dmabuf_try (allocator, ¶ms))
|
|
||||||
return FALSE;
|
|
||||||
} else if (GST_IS_VA_ALLOCATOR (allocator)) {
|
|
||||||
if (!gst_va_allocator_try (allocator, ¶ms))
|
|
||||||
return FALSE;
|
|
||||||
} else {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstAllocator *
|
static GstAllocator *
|
||||||
_create_allocator (GstVaVpp * self, GstCaps * caps, guint usage_hint)
|
_create_allocator (GstVaVpp * self, GstCaps * caps, guint usage_hint)
|
||||||
{
|
{
|
||||||
|
@ -430,9 +407,6 @@ _create_allocator (GstVaVpp * self, GstCaps * caps, guint usage_hint)
|
||||||
allocator = gst_va_allocator_new (self->display, surface_formats);
|
allocator = gst_va_allocator_new (self->display, surface_formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_try_allocator (self, allocator, caps, usage_hint))
|
|
||||||
gst_clear_object (&allocator);
|
|
||||||
|
|
||||||
return allocator;
|
return allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue