Enable zero-copy support for gstreamer video decoders
[vlc.git] / modules / codec / gstreamer / gstvlcvideopool.c
blob35229a3800dbade6941a0958da02ba0da9a06e78
1 /*****************************************************************************
2 * gstvlcvideopool.c: VLC pictures managed by GstBufferPool
3 *****************************************************************************
4 * Copyright (C) 2016 VLC authors and VideoLAN
5 * $Id:
7 * Author: Vikram Fugro <vikram.fugro@gmail.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
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.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #include "gstvlcvideopool.h"
29 #include <vlc_common.h>
31 /* bufferpool */
32 static void gst_vlc_video_pool_finalize( GObject *p_object );
34 #define gst_vlc_video_pool_parent_class parent_class
35 G_DEFINE_TYPE (GstVlcVideoPool, gst_vlc_video_pool,
36 GST_TYPE_BUFFER_POOL);
38 static const gchar** gst_vlc_video_pool_get_options (GstBufferPool *p_pool)
40 static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META,
41 NULL
44 return options;
47 static gboolean gst_vlc_video_pool_set_config( GstBufferPool *p_pool,
48 GstStructure *p_config )
50 GstVlcVideoPool *p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
51 GstCaps *p_caps;
52 GstVideoInfo info;
53 guint size, min_buffers, max_buffers;
54 GstAllocator *p_allocator;
55 GstAllocationParams params;
57 if( !gst_buffer_pool_config_get_params( p_config, &p_caps, &size,
58 &min_buffers, &max_buffers ))
59 goto wrong_config;
61 if( p_caps == NULL )
62 goto no_caps;
64 gst_buffer_pool_config_get_allocator( p_config, &p_allocator, &params );
65 if( p_allocator )
67 if( !GST_IS_VLC_PICTURE_PLANE_ALLOCATOR( p_allocator ))
68 goto unsupported_allocator;
69 else
71 if( p_vpool->p_allocator )
72 gst_object_unref( p_vpool->p_allocator );
73 p_vpool->p_allocator = gst_object_ref ( p_allocator );
77 /* now parse the caps from the config */
78 if ( !gst_video_info_from_caps( &info, p_caps ))
79 goto wrong_caps;
81 /* enable metadata based on config of the pool */
82 p_vpool->b_add_metavideo =
83 gst_buffer_pool_config_has_option( p_config,
84 GST_BUFFER_POOL_OPTION_VIDEO_META );
86 if( !gst_vlc_picture_plane_allocator_query_format( p_vpool->p_allocator,
87 &info, p_caps))
88 goto unknown_format;
90 if( p_vpool->p_caps )
91 gst_caps_unref( p_vpool->p_caps );
92 p_vpool->p_caps = gst_caps_ref( p_caps );
93 p_vpool->info = info;
95 gst_buffer_pool_config_set_params( p_config, p_caps, info.size,
96 min_buffers, max_buffers );
98 return GST_BUFFER_POOL_CLASS (parent_class)->set_config( p_pool, p_config );
100 /* ERRORS */
101 wrong_config:
103 msg_Err(p_vpool->p_dec, "wrong pool config" );
104 return FALSE;
106 no_caps:
108 msg_Err(p_vpool->p_dec, "no input caps in config" );
109 return FALSE;
111 wrong_caps:
113 msg_Err(p_vpool->p_dec, "invalid caps" );
114 return FALSE;
116 unknown_format:
118 msg_Err(p_vpool->p_dec, "format unsupported" );
119 return FALSE;
121 unsupported_allocator:
123 msg_Err(p_vpool->p_dec, "allocator unsupported" );
124 return FALSE;
128 static GstFlowReturn gst_vlc_video_pool_acquire_buffer( GstBufferPool *p_pool,
129 GstBuffer **p_buffer, GstBufferPoolAcquireParams *p_params )
131 GstVlcVideoPool *p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
132 GstVideoInfo *p_info;
133 GstFlowReturn result;
135 result = GST_BUFFER_POOL_CLASS( parent_class)->acquire_buffer( p_pool,
136 p_buffer, p_params );
138 if( result == GST_FLOW_OK &&
139 !gst_vlc_picture_plane_allocator_hold( p_vpool->p_allocator,
140 *p_buffer ))
141 result = GST_FLOW_EOS;
143 return result;
146 static void gst_vlc_video_pool_release_buffer( GstBufferPool *p_pool,
147 GstBuffer *p_buffer )
149 GstVlcVideoPool* p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
151 gst_vlc_picture_plane_allocator_release( p_vpool->p_allocator, p_buffer );
153 GST_BUFFER_POOL_CLASS( parent_class )->release_buffer( p_pool, p_buffer );
155 return;
158 static void gst_vlc_video_pool_free_buffer( GstBufferPool *p_pool,
159 GstBuffer *p_buffer )
161 GstVlcVideoPool* p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
163 gst_vlc_picture_plane_allocator_release( p_vpool->p_allocator, p_buffer );
165 GST_BUFFER_POOL_CLASS( parent_class )->free_buffer( p_pool, p_buffer );
167 return;
170 static GstFlowReturn gst_vlc_video_pool_alloc_buffer( GstBufferPool *p_pool,
171 GstBuffer **p_buffer, GstBufferPoolAcquireParams *p_params)
173 GstVlcVideoPool *p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
174 GstVideoInfo *p_info = &p_vpool->info;
176 *p_buffer = gst_buffer_new( );
178 if( !gst_vlc_picture_plane_allocator_alloc( p_vpool->p_allocator,
179 *p_buffer ))
180 return GST_FLOW_EOS;
182 if( p_vpool->b_add_metavideo )
184 msg_Dbg( p_vpool->p_dec, "meta video enabled" );
185 gst_buffer_add_video_meta_full( *p_buffer, GST_VIDEO_FRAME_FLAG_NONE,
186 GST_VIDEO_INFO_FORMAT( p_info ), GST_VIDEO_INFO_WIDTH( p_info ),
187 GST_VIDEO_INFO_HEIGHT( p_info ),
188 GST_VIDEO_INFO_N_PLANES( p_info ),
189 p_info->offset, p_info->stride );
192 return GST_FLOW_OK;
195 static void gst_vlc_video_pool_class_init( GstVlcVideoPoolClass *p_klass )
197 GObjectClass *p_gobject_class = ( GObjectClass* )p_klass;
198 GstBufferPoolClass *p_gstbufferpool_class = ( GstBufferPoolClass* )p_klass;
200 p_gobject_class->finalize = gst_vlc_video_pool_finalize;
202 p_gstbufferpool_class->get_options = gst_vlc_video_pool_get_options;
203 p_gstbufferpool_class->set_config = gst_vlc_video_pool_set_config;
204 p_gstbufferpool_class->alloc_buffer = gst_vlc_video_pool_alloc_buffer;
205 p_gstbufferpool_class->free_buffer = gst_vlc_video_pool_free_buffer;
206 p_gstbufferpool_class->acquire_buffer = gst_vlc_video_pool_acquire_buffer;
207 p_gstbufferpool_class->release_buffer = gst_vlc_video_pool_release_buffer;
210 static void gst_vlc_video_pool_init( GstVlcVideoPool *p_pool )
214 static void gst_vlc_video_pool_finalize( GObject *p_object )
216 GstVlcVideoPool *p_pool = GST_VLC_VIDEO_POOL_CAST( p_object );
218 gst_object_unref( p_pool->p_allocator );
220 G_OBJECT_CLASS( parent_class )->finalize( p_object );
223 GstVlcVideoPool* gst_vlc_video_pool_new(
224 GstAllocator *p_allocator, decoder_t *p_dec )
226 GstVlcVideoPool *p_pool;
228 if( !GST_IS_VLC_PICTURE_PLANE_ALLOCATOR( p_allocator ))
230 msg_Err( p_pool->p_dec, "unspported allocator for pool" );
231 return NULL;
234 p_pool = g_object_new( GST_TYPE_VLC_VIDEO_POOL, NULL );
235 p_pool->p_allocator = gst_object_ref( p_allocator );
236 p_pool->p_dec = p_dec;
238 return p_pool;