5ad85f0e5316390512daa78dda48950d0bc0a355
[platform/upstream/gstreamer.git] / subprojects / gstreamer-vaapi / gst-libs / gst / vaapi / gstvaapisurfacepool.c
1 /*
2  *  gstvaapisurfacepool.c - Gst VA surface pool
3  *
4  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5  *    Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6  *  Copyright (C) 2012-2013 Intel Corporation
7  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public License
11  *  as published by the Free Software Foundation; either version 2.1
12  *  of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; if not, write to the Free
21  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  *  Boston, MA 02110-1301 USA
23  */
24
25 /**
26  * SECTION:gstvaapisurfacepool
27  * @short_description: VA surface pool
28  */
29
30 #include "sysdeps.h"
31 #include "gstvaapisurfacepool.h"
32 #include "gstvaapivideopool_priv.h"
33
34 #define DEBUG 1
35 #include "gstvaapidebug.h"
36
37 /**
38  * GstVaapiSurfacePool:
39  *
40  * A pool of lazily allocated #GstVaapiSurface objects.
41  */
42 struct _GstVaapiSurfacePool
43 {
44   /*< private > */
45   GstVaapiVideoPool parent_instance;
46
47   GstVaapiChromaType chroma_type;
48   GstVideoInfo video_info;
49   guint alloc_flags;
50 };
51
52 static gboolean
53 surface_pool_init (GstVaapiSurfacePool * pool, const GstVideoInfo * vip,
54     guint surface_allocation_flags)
55 {
56   const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (vip);
57
58   pool->video_info = *vip;
59   pool->alloc_flags = surface_allocation_flags;
60
61   if (format == GST_VIDEO_FORMAT_UNKNOWN)
62     return FALSE;
63
64   if (format == GST_VIDEO_FORMAT_ENCODED)
65     pool->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
66   else
67     pool->chroma_type = gst_vaapi_video_format_get_chroma_type (format);
68   if (!pool->chroma_type)
69     return FALSE;
70   return TRUE;
71 }
72
73 static gpointer
74 gst_vaapi_surface_pool_alloc_object (GstVaapiVideoPool * base_pool)
75 {
76   GstVaapiSurfacePool *const pool = GST_VAAPI_SURFACE_POOL (base_pool);
77
78   /* Try to allocate a surface with an explicit pixel format first */
79   if (GST_VIDEO_INFO_FORMAT (&pool->video_info) != GST_VIDEO_FORMAT_ENCODED) {
80     GstVaapiSurface *const surface =
81         gst_vaapi_surface_new_full (base_pool->display, &pool->video_info,
82         pool->alloc_flags);
83     if (surface)
84       return surface;
85   }
86
87   /* Otherwise, fallback to the original interface, based on chroma format */
88   return gst_vaapi_surface_new (base_pool->display,
89       pool->chroma_type, GST_VIDEO_INFO_WIDTH (&pool->video_info),
90       GST_VIDEO_INFO_HEIGHT (&pool->video_info));
91 }
92
93 static inline const GstVaapiMiniObjectClass *
94 gst_vaapi_surface_pool_class (void)
95 {
96   static const GstVaapiVideoPoolClass GstVaapiSurfacePoolClass = {
97     {sizeof (GstVaapiSurfacePool),
98         (GDestroyNotify) gst_vaapi_video_pool_finalize}
99     ,
100     .alloc_object = gst_vaapi_surface_pool_alloc_object
101   };
102   return GST_VAAPI_MINI_OBJECT_CLASS (&GstVaapiSurfacePoolClass);
103 }
104
105 /**
106  * gst_vaapi_surface_pool_new:
107  * @display: a #GstVaapiDisplay
108  * @format: a #GstVideoFormat
109  * @width: the desired width, in pixels
110  * @height: the desired height, in pixels
111  * @surface_allocation_flags: (optional) allocation flags
112  *
113  * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the specified
114  * format and dimensions. If @format is GST_VIDEO_FORMAT_ENCODED, then
115  * surfaces with best "native" format would be created. Typically, this is
116  * NV12 format, but this is implementation (driver) defined.
117  *
118  * Return value: the newly allocated #GstVaapiVideoPool
119  */
120 GstVaapiVideoPool *
121 gst_vaapi_surface_pool_new (GstVaapiDisplay * display, GstVideoFormat format,
122     guint width, guint height, guint surface_allocation_flags)
123 {
124   GstVideoInfo vi;
125
126   g_return_val_if_fail (display != NULL, NULL);
127   g_return_val_if_fail (width > 0, NULL);
128   g_return_val_if_fail (height > 0, NULL);
129
130   gst_video_info_set_format (&vi, format, width, height);
131   return gst_vaapi_surface_pool_new_full (display, &vi,
132       surface_allocation_flags);
133 }
134
135 /**
136  * gst_vaapi_surface_pool_new_full:
137  * @display: a #GstVaapiDisplay
138  * @vip: a #GstVideoInfo
139  * @surface_allocation_flags: (optional) allocation flags
140  *
141  * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the
142  * specified format and dimensions in @vip.
143  *
144  * Return value: the newly allocated #GstVaapiVideoPool
145  */
146 GstVaapiVideoPool *
147 gst_vaapi_surface_pool_new_full (GstVaapiDisplay * display,
148     const GstVideoInfo * vip, guint surface_allocation_flags)
149 {
150   GstVaapiVideoPool *pool;
151
152   g_return_val_if_fail (display != NULL, NULL);
153   g_return_val_if_fail (vip != NULL, NULL);
154
155   pool = (GstVaapiVideoPool *)
156       gst_vaapi_mini_object_new (gst_vaapi_surface_pool_class ());
157   if (!pool)
158     return NULL;
159
160   gst_vaapi_video_pool_init (pool, display,
161       GST_VAAPI_VIDEO_POOL_OBJECT_TYPE_SURFACE);
162   if (!surface_pool_init (GST_VAAPI_SURFACE_POOL (pool), vip,
163           surface_allocation_flags))
164     goto error;
165   return pool;
166
167   /* ERRORS */
168 error:
169   {
170     gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (pool));
171     return NULL;
172   }
173 }
174
175 /**
176  * gst_vaapi_surface_pool_new_with_chroma_type:
177  * @display: a #GstVaapiDisplay
178  * @chroma_type: a #GstVaapiChromatype
179  * @width: the desired width, in pixels
180  * @height: the desired height, in pixels
181  * @surface_allocation_flags: (optional) allocation flags
182  *
183  * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the specified
184  * chroma type and dimensions. The underlying format of the surfaces is
185  * implementation (driver) defined.
186  *
187  * Return value: the newly allocated #GstVaapiVideoPool
188  */
189 GstVaapiVideoPool *
190 gst_vaapi_surface_pool_new_with_chroma_type (GstVaapiDisplay * display,
191     GstVaapiChromaType chroma_type, guint width, guint height,
192     guint surface_allocation_flags)
193 {
194   GstVaapiVideoPool *pool;
195   GstVideoInfo vi;
196
197   g_return_val_if_fail (display != NULL, NULL);
198   g_return_val_if_fail (chroma_type > 0, NULL);
199   g_return_val_if_fail (width > 0, NULL);
200   g_return_val_if_fail (height > 0, NULL);
201
202   gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_ENCODED, width, height);
203
204   pool =
205       gst_vaapi_surface_pool_new_full (display, &vi, surface_allocation_flags);
206   if (!pool)
207     return NULL;
208
209   GST_VAAPI_SURFACE_POOL (pool)->chroma_type = chroma_type;
210
211   return pool;
212 }