1 /*****************************************************************************
2 * gstvlcvideopool.c: VLC pictures managed by GstBufferPool
3 *****************************************************************************
4 * Copyright (C) 2016 VLC authors and VideoLAN
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 /*****************************************************************************
26 *****************************************************************************/
27 #include "gstvlcvideopool.h"
29 #include <vlc_common.h>
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
,
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
);
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
))
64 gst_buffer_pool_config_get_allocator( p_config
, &p_allocator
, ¶ms
);
67 if( !GST_IS_VLC_PICTURE_PLANE_ALLOCATOR( p_allocator
))
68 goto unsupported_allocator
;
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
))
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
,
91 gst_caps_unref( p_vpool
->p_caps
);
92 p_vpool
->p_caps
= gst_caps_ref( p_caps
);
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
);
103 msg_Err(p_vpool
->p_dec
, "wrong pool config" );
108 msg_Err(p_vpool
->p_dec
, "no input caps in config" );
113 msg_Err(p_vpool
->p_dec
, "invalid caps" );
118 msg_Err(p_vpool
->p_dec
, "format unsupported" );
121 unsupported_allocator
:
123 msg_Err(p_vpool
->p_dec
, "allocator unsupported" );
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
,
141 result
= GST_FLOW_EOS
;
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
);
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
);
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
,
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
);
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" );
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
;