xref: /OK3568_Linux_fs/external/gstreamer-rockchip/gst/rkximage/gstkmsbufferpool.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * GStreamer
3*4882a593Smuzhiyun  * Copyright (C) 2016 Igalia
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Authors:
6*4882a593Smuzhiyun  *  Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
7*4882a593Smuzhiyun  *  Javier Martin <javiermartin@by.com.es>
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * This library is free software; you can redistribute it and/or
10*4882a593Smuzhiyun  * modify it under the terms of the GNU Library General Public
11*4882a593Smuzhiyun  * License as published by the Free Software Foundation; either
12*4882a593Smuzhiyun  * version 2 of the License, or (at your option) any later version.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * This library is distributed in the hope that it will be useful,
15*4882a593Smuzhiyun  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16*4882a593Smuzhiyun  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17*4882a593Smuzhiyun  * Library General Public License for more details.
18*4882a593Smuzhiyun  *
19*4882a593Smuzhiyun  * You should have received a copy of the GNU Library General Public
20*4882a593Smuzhiyun  * License along with this library; if not, write to the
21*4882a593Smuzhiyun  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22*4882a593Smuzhiyun  * Boston, MA 02110-1301, USA.
23*4882a593Smuzhiyun  *
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #ifdef HAVE_CONFIG_H
27*4882a593Smuzhiyun #include "config.h"
28*4882a593Smuzhiyun #endif
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #include <gst/video/gstvideometa.h>
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #include "gstkmsbufferpool.h"
33*4882a593Smuzhiyun #include "gstkmsallocator.h"
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun GST_DEBUG_CATEGORY_STATIC (gst_kms_buffer_pool_debug);
36*4882a593Smuzhiyun #define GST_CAT_DEFAULT gst_kms_buffer_pool_debug
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun struct _GstKMSBufferPoolPrivate
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun   GstVideoInfo vinfo;
41*4882a593Smuzhiyun   GstAllocator *allocator;
42*4882a593Smuzhiyun   gboolean add_videometa;
43*4882a593Smuzhiyun   gboolean has_prime_export;
44*4882a593Smuzhiyun };
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun #define parent_class gst_kms_buffer_pool_parent_class
47*4882a593Smuzhiyun G_DEFINE_TYPE_WITH_CODE (GstKMSBufferPool, gst_kms_buffer_pool,
48*4882a593Smuzhiyun     GST_TYPE_VIDEO_BUFFER_POOL, G_ADD_PRIVATE (GstKMSBufferPool);
49*4882a593Smuzhiyun     GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "kmsbufferpool", 0,
50*4882a593Smuzhiyun         "KMS buffer pool"));
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun static const gchar **
gst_kms_buffer_pool_get_options(GstBufferPool * pool)53*4882a593Smuzhiyun gst_kms_buffer_pool_get_options (GstBufferPool * pool)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun   static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META,
56*4882a593Smuzhiyun     GST_BUFFER_POOL_OPTION_KMS_BUFFER,
57*4882a593Smuzhiyun     GST_BUFFER_POOL_OPTION_KMS_PRIME_EXPORT,
58*4882a593Smuzhiyun     NULL
59*4882a593Smuzhiyun   };
60*4882a593Smuzhiyun   return options;
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun static gboolean
gst_kms_buffer_pool_set_config(GstBufferPool * pool,GstStructure * config)64*4882a593Smuzhiyun gst_kms_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun   GstKMSBufferPool *vpool;
67*4882a593Smuzhiyun   GstKMSBufferPoolPrivate *priv;
68*4882a593Smuzhiyun   GstCaps *caps;
69*4882a593Smuzhiyun   GstVideoInfo vinfo;
70*4882a593Smuzhiyun   GstAllocator *allocator;
71*4882a593Smuzhiyun   GstAllocationParams params;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun   vpool = GST_KMS_BUFFER_POOL_CAST (pool);
74*4882a593Smuzhiyun   priv = vpool->priv;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun   if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
77*4882a593Smuzhiyun     goto wrong_config;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun   if (!caps)
80*4882a593Smuzhiyun     goto no_caps;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun   /* now parse the caps from the config */
83*4882a593Smuzhiyun   if (!gst_video_info_from_caps (&vinfo, caps))
84*4882a593Smuzhiyun     goto wrong_caps;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun   allocator = NULL;
87*4882a593Smuzhiyun   gst_buffer_pool_config_get_allocator (config, &allocator, &params);
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun   /* not our allocator, not our buffers */
90*4882a593Smuzhiyun   if (allocator && GST_IS_KMS_ALLOCATOR (allocator)) {
91*4882a593Smuzhiyun     if (priv->allocator)
92*4882a593Smuzhiyun       gst_object_unref (priv->allocator);
93*4882a593Smuzhiyun     priv->allocator = gst_object_ref (allocator);
94*4882a593Smuzhiyun   }
95*4882a593Smuzhiyun   if (!priv->allocator)
96*4882a593Smuzhiyun     goto no_allocator;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun   priv->vinfo = vinfo;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun   /* enable metadata based on config of the pool */
101*4882a593Smuzhiyun   priv->add_videometa = gst_buffer_pool_config_has_option (config,
102*4882a593Smuzhiyun       GST_BUFFER_POOL_OPTION_VIDEO_META);
103*4882a593Smuzhiyun   priv->has_prime_export = gst_buffer_pool_config_has_option (config,
104*4882a593Smuzhiyun       GST_BUFFER_POOL_OPTION_KMS_PRIME_EXPORT);
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun   return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun   /* ERRORS */
109*4882a593Smuzhiyun wrong_config:
110*4882a593Smuzhiyun   {
111*4882a593Smuzhiyun     GST_WARNING_OBJECT (pool, "invalid config");
112*4882a593Smuzhiyun     return FALSE;
113*4882a593Smuzhiyun   }
114*4882a593Smuzhiyun no_caps:
115*4882a593Smuzhiyun   {
116*4882a593Smuzhiyun     GST_WARNING_OBJECT (pool, "no caps in config");
117*4882a593Smuzhiyun     return FALSE;
118*4882a593Smuzhiyun   }
119*4882a593Smuzhiyun wrong_caps:
120*4882a593Smuzhiyun   {
121*4882a593Smuzhiyun     GST_WARNING_OBJECT (pool,
122*4882a593Smuzhiyun         "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
123*4882a593Smuzhiyun     return FALSE;
124*4882a593Smuzhiyun   }
125*4882a593Smuzhiyun no_allocator:
126*4882a593Smuzhiyun   {
127*4882a593Smuzhiyun     GST_WARNING_OBJECT (pool, "no valid allocator in pool");
128*4882a593Smuzhiyun     return FALSE;
129*4882a593Smuzhiyun   }
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun static GstFlowReturn
gst_kms_buffer_pool_alloc_buffer(GstBufferPool * pool,GstBuffer ** buffer,GstBufferPoolAcquireParams * params)133*4882a593Smuzhiyun gst_kms_buffer_pool_alloc_buffer (GstBufferPool * pool, GstBuffer ** buffer,
134*4882a593Smuzhiyun     GstBufferPoolAcquireParams * params)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun   GstKMSBufferPool *vpool;
137*4882a593Smuzhiyun   GstKMSBufferPoolPrivate *priv;
138*4882a593Smuzhiyun   GstVideoInfo *info;
139*4882a593Smuzhiyun   GstMemory *mem;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun   vpool = GST_KMS_BUFFER_POOL_CAST (pool);
142*4882a593Smuzhiyun   priv = vpool->priv;
143*4882a593Smuzhiyun   info = &priv->vinfo;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun   mem = gst_kms_allocator_bo_alloc (priv->allocator, info);
146*4882a593Smuzhiyun   if (!mem)
147*4882a593Smuzhiyun     goto no_memory;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun   if (vpool->priv->has_prime_export) {
150*4882a593Smuzhiyun     GstMemory *dmabufmem;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun     dmabufmem = gst_kms_allocator_dmabuf_export (priv->allocator, mem);
153*4882a593Smuzhiyun     if (dmabufmem)
154*4882a593Smuzhiyun       mem = dmabufmem;
155*4882a593Smuzhiyun     else
156*4882a593Smuzhiyun       GST_WARNING_OBJECT (pool, "Failed to export DMABuf from Dumb buffer.");
157*4882a593Smuzhiyun   }
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun   *buffer = gst_buffer_new ();
160*4882a593Smuzhiyun   gst_buffer_append_memory (*buffer, mem);
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun   if (priv->add_videometa) {
163*4882a593Smuzhiyun     GST_DEBUG_OBJECT (pool, "adding GstVideoMeta");
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun     gst_buffer_add_video_meta_full (*buffer, GST_VIDEO_FRAME_FLAG_NONE,
166*4882a593Smuzhiyun         GST_VIDEO_INFO_FORMAT (info),
167*4882a593Smuzhiyun         GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info),
168*4882a593Smuzhiyun         GST_VIDEO_INFO_N_PLANES (info), info->offset, info->stride);
169*4882a593Smuzhiyun   }
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun   return GST_FLOW_OK;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun   /* ERROR */
174*4882a593Smuzhiyun no_memory:
175*4882a593Smuzhiyun   {
176*4882a593Smuzhiyun     GST_WARNING_OBJECT (pool, "can't create memory");
177*4882a593Smuzhiyun     return GST_FLOW_ERROR;
178*4882a593Smuzhiyun   }
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun static void
gst_kms_buffer_pool_finalize(GObject * object)182*4882a593Smuzhiyun gst_kms_buffer_pool_finalize (GObject * object)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun   GstKMSBufferPool *pool;
185*4882a593Smuzhiyun   GstKMSBufferPoolPrivate *priv;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun   pool = GST_KMS_BUFFER_POOL (object);
188*4882a593Smuzhiyun   priv = pool->priv;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun   if (priv->allocator)
191*4882a593Smuzhiyun     gst_object_unref (priv->allocator);
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun   G_OBJECT_CLASS (parent_class)->finalize (object);
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun static void
gst_kms_buffer_pool_init(GstKMSBufferPool * pool)197*4882a593Smuzhiyun gst_kms_buffer_pool_init (GstKMSBufferPool * pool)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun   pool->priv = gst_kms_buffer_pool_get_instance_private (pool);
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun static void
gst_kms_buffer_pool_class_init(GstKMSBufferPoolClass * klass)203*4882a593Smuzhiyun gst_kms_buffer_pool_class_init (GstKMSBufferPoolClass * klass)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun   GObjectClass *gobject_class;
206*4882a593Smuzhiyun   GstBufferPoolClass *gstbufferpool_class;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun   gobject_class = (GObjectClass *) klass;
209*4882a593Smuzhiyun   gstbufferpool_class = (GstBufferPoolClass *) klass;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun   gobject_class->finalize = gst_kms_buffer_pool_finalize;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun   gstbufferpool_class->get_options = gst_kms_buffer_pool_get_options;
214*4882a593Smuzhiyun   gstbufferpool_class->set_config = gst_kms_buffer_pool_set_config;
215*4882a593Smuzhiyun   gstbufferpool_class->alloc_buffer = gst_kms_buffer_pool_alloc_buffer;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun GstBufferPool *
gst_kms_buffer_pool_new(void)219*4882a593Smuzhiyun gst_kms_buffer_pool_new (void)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun   GstBufferPool *pool;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun   pool = g_object_new (GST_TYPE_KMS_BUFFER_POOL, NULL);
224*4882a593Smuzhiyun   gst_object_ref_sink (pool);
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun   return pool;
227*4882a593Smuzhiyun }
228