Fix the typecast warnings:
[vaapi:sree-gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapisurfacepool.c
1 /*
2  *  gstvaapisurfacepool.c - Gst VA surface pool
3  *
4  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public License
8  *  as published by the Free Software Foundation; either version 2.1
9  *  of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free
18  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * SECTION:gstvaapisurfacepool
24  * @short_description: VA surface pool
25  */
26
27 #include "sysdeps.h"
28 #include "gstvaapisurfacepool.h"
29 #include "gstvaapisurfaceproxy.h"
30 #define DEBUG 1
31 #include "gstvaapidebug.h"
32
33 struct _GstVaapiSurfacePoolPrivate {
34     GstAllocator        *allocator;
35   
36     GstVaapiDisplay     *display;
37  
38     GstVaapiImageFormat yuv_format; 
39     GstVaapiChromaType  chroma_type;
40
41     GstVideoInfo        info;
42     guint               add_videometa          :1;
43     guint               add_vaapi_surface_meta :1; 
44 };
45
46 G_DEFINE_TYPE(
47     GstVaapiSurfacePool,
48     gst_vaapi_surface_pool,
49     GST_VAAPI_TYPE_VIDEO_POOL)
50
51 #define GST_VAAPI_SURFACE_POOL_GET_PRIVATE(obj)                 \
52     (G_TYPE_INSTANCE_GET_PRIVATE((obj),                         \
53                                  GST_VAAPI_TYPE_SURFACE_POOL,   \
54                                  GstVaapiSurfacePoolPrivate))
55
56 /*Fixme: this will go away once we directly subclass surfacepoool from bufferpool*/
57 static void
58 gst_vaapi_surface_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps)
59 {
60     GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL(pool)->priv;
61     GstStructure *structure;
62     GstVideoInfo info;
63
64     if (!gst_video_info_from_caps (&info, caps))
65     {
66         GST_ERROR ("Failed to parse video info");
67         return;
68     }
69     priv->info          = info;
70     priv->chroma_type   = GST_VAAPI_CHROMA_TYPE_YUV420;
71 }
72
73 static const gchar **
74 gst_vaapi_surface_pool_get_options (GstBufferPool * pool)
75 {
76   static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META,
77     GST_BUFFER_POOL_OPTION_VAAPI_SURFACE_META, NULL
78   };
79
80   return options;
81 }
82
83 static gboolean
84 ensure_surface_memory (GstBufferPool *pool, GstVideoInfo *info)
85 {
86     GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL(pool)->priv;
87     GstVaapiDisplay *display = gst_vaapi_video_pool_get_display (GST_VAAPI_VIDEO_POOL(pool));
88  
89     if(!priv->allocator) 
90        priv->allocator = gst_allocator_find(GST_VAAPI_SURFACE_ALLOCATOR_NAME);
91 }
92
93 static gboolean
94 gst_vaapi_surface_pool_set_config (GstBufferPool * pool, GstStructure * config)
95 {
96     GstVaapiSurfacePool *surface_pool = GST_VAAPI_SURFACE_POOL (pool);
97     GstVaapiSurfacePoolPrivate *priv = surface_pool->priv;
98     GstVaapiDisplay *display;
99     GstAllocationParams params;
100     GstVideoInfo info;
101     GstCaps *caps;
102
103     if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
104         goto wrong_config;
105
106     if (caps == NULL)
107        goto no_caps;
108
109     /* now parse the caps from the config */
110     if (!gst_video_info_from_caps (&info, caps))
111        goto wrong_caps;
112
113     GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, info.width, info.height,
114         caps);
115
116     priv->chroma_type   = GST_VAAPI_CHROMA_TYPE_YUV420;
117     priv->info          = info;
118     priv->display       = gst_vaapi_video_pool_get_display (GST_VAAPI_VIDEO_POOL(pool));
119     
120     /*Fixme: move this to vaapisink:propose_allocation*/
121     gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VAAPI_SURFACE_META);
122     gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
123     
124     if (!priv->allocator)    
125         priv->allocator = gst_allocator_find(GST_VAAPI_SURFACE_ALLOCATOR_NAME);
126
127     gst_allocation_params_init(&params);
128     gst_buffer_pool_config_set_allocator(config, priv->allocator, &params);
129
130     /* enable metadata based on config of the pool */
131     priv->add_videometa =
132         gst_buffer_pool_config_has_option (config,
133         GST_BUFFER_POOL_OPTION_VIDEO_META);
134
135     /* parse extra alignment info */
136     priv->add_vaapi_surface_meta = gst_buffer_pool_config_has_option (config,
137         GST_BUFFER_POOL_OPTION_VAAPI_SURFACE_META);
138
139     return GST_BUFFER_POOL_CLASS (gst_vaapi_surface_pool_parent_class)->set_config (pool, config);
140
141     /* ERRORS */
142 wrong_config:
143     {
144         GST_WARNING_OBJECT (pool, "invalid config");
145         return FALSE;
146     }
147
148    no_caps:
149     {
150         GST_WARNING_OBJECT (pool, "no caps in config");
151         return FALSE;
152     }
153
154 wrong_caps:
155     {
156         GST_WARNING_OBJECT (pool,
157             "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
158         return FALSE;
159     } 
160 }
161   
162 static GstFlowReturn
163 gst_vaapi_surface_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
164     GstBufferPoolAcquireParams * buf_alloc_params)
165 {
166
167    GstBuffer *surface_buffer;
168    GstVaapiDisplay *display;
169    GstMemory *surface_mem;
170    GstAllocationParams params;
171    GstVaapiSurfaceMeta *meta;
172    GstVideoInfo *info;
173
174    GstVaapiVideoPool *video_pool = GST_VAAPI_VIDEO_POOL (pool);
175    GstVaapiSurfacePool *surface_pool = GST_VAAPI_SURFACE_POOL (pool);
176    GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL(pool)->priv;
177
178    info = &priv->info;
179
180    display = gst_vaapi_video_pool_get_display (video_pool);
181
182    if (!(surface_mem = gst_vaapi_surface_memory_new(display,info))) {
183         GST_ERROR("Failed to create the VA Surface Memory");
184         return FALSE;
185    }
186
187    surface_buffer = gst_buffer_new ();
188    gst_buffer_insert_memory (surface_buffer, -1, (GstMemory *)surface_mem);
189    GST_BUFFER_OFFSET(surface_buffer) = 0;
190    GST_BUFFER_TIMESTAMP(surface_buffer) = 0;
191   
192    if(priv->add_vaapi_surface_meta) {
193        meta = gst_buffer_add_vaapi_surface_meta (surface_buffer, display);
194        if (!meta) {
195            gst_buffer_unref(surface_buffer);
196            goto no_buffer;
197        }
198    }
199    
200    if (priv->add_videometa) {
201        GstVideoMeta *vmeta;
202
203        GST_DEBUG_OBJECT (pool, "adding GstVideoMeta");
204        /* these are just the defaults for now */
205        vmeta = gst_buffer_add_video_meta (surface_buffer, 0, GST_VIDEO_INFO_FORMAT (info),
206            GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info));
207        
208        vmeta->map   = gst_vaapi_video_memory_map;
209        vmeta->unmap = gst_vaapi_video_memory_unmap;
210    }
211  
212    *buffer = surface_buffer;
213    return GST_FLOW_OK;
214
215 /* ERROR */
216 no_buffer:
217    {
218        GST_WARNING_OBJECT (pool, "can't create image");
219        return GST_FLOW_ERROR;
220    }
221 }
222
223 static void
224 gst_vaapi_surface_pool_finalize(GObject *object)
225 {
226     GstVaapiSurfacePool *pool = GST_VAAPI_SURFACE_POOL (object);
227     GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL_GET_PRIVATE(pool);
228
229     if (priv->allocator)
230         gst_object_unref (GST_OBJECT(priv->allocator));
231
232     G_OBJECT_CLASS(gst_vaapi_surface_pool_parent_class)->finalize(object);
233 }
234
235 static void
236 gst_vaapi_surface_pool_class_init(GstVaapiSurfacePoolClass *klass)
237 {
238     GObjectClass * const object_class = G_OBJECT_CLASS(klass);
239     GstVaapiVideoPoolClass * const pool_class = GST_VAAPI_VIDEO_POOL_CLASS(klass);
240     GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
241
242     g_type_class_add_private(klass, sizeof(GstVaapiSurfacePoolPrivate));
243
244     object_class->finalize      = gst_vaapi_surface_pool_finalize;
245
246     pool_class->set_caps        = gst_vaapi_surface_pool_set_caps;
247
248     gstbufferpool_class->get_options  = gst_vaapi_surface_pool_get_options;
249     gstbufferpool_class->set_config   = gst_vaapi_surface_pool_set_config;
250     gstbufferpool_class->alloc_buffer = gst_vaapi_surface_pool_alloc;
251 }
252
253 static void
254 gst_vaapi_surface_pool_init(GstVaapiSurfacePool *pool)
255 {
256     GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL_GET_PRIVATE(pool);
257
258     pool->priv                   = priv;
259     priv->chroma_type            = 0;
260     priv->allocator              = NULL;
261     priv->add_videometa          = FALSE;
262     priv->add_vaapi_surface_meta = FALSE;
263 }
264
265 /**
266  * gst_vaapi_surface_pool_new:
267  * @display: a #GstVaapiDisplay
268  * @caps: a #GstCaps
269  *
270  * Creates a new #GstVaapiVideoPool of #GstVaapiSurface with the
271  * specified dimensions in @caps.
272  *
273  * Return value: the newly allocated #GstVaapiVideoPool
274  */
275 GstBufferPool *
276 gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps)
277 {
278     GstVaapiVideoPool *pool;
279     GstVideoInfo info;
280     
281     pool = g_object_new(GST_VAAPI_TYPE_SURFACE_POOL,
282                         "display", display,
283                         "caps",    caps,
284                         NULL);
285
286     gst_vaapi_surface_memory_allocator_setup();
287
288     return GST_BUFFER_POOL_CAST(pool);
289 }