/*****************************************************************************
* gstvlcvideopool.c: VLC pictures managed by GstBufferPool
*****************************************************************************
* Copyright (C) 2016 VLC authors and VideoLAN
*
* Author: Vikram Fugro <vikram.fugro@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "gstvlcvideopool.h"
#include <vlc_common.h>
/* bufferpool */
static void gst_vlc_video_pool_finalize( GObject *p_object );
#define gst_vlc_video_pool_parent_class parent_class
G_DEFINE_TYPE (GstVlcVideoPool, gst_vlc_video_pool,
GST_TYPE_BUFFER_POOL)
static const gchar** gst_vlc_video_pool_get_options (GstBufferPool *p_pool)
{
VLC_UNUSED( p_pool );
static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META,
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT, NULL
};
return options;
}
static gboolean gst_vlc_video_pool_set_config( GstBufferPool *p_pool,
GstStructure *p_config )
{
GstVlcVideoPool *p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
GstCaps *p_caps;
GstVideoInfo info;
GstVideoAlignment align;
guint size, min_buffers, max_buffers;
GstAllocator *p_allocator;
GstAllocationParams params;
if( !gst_buffer_pool_config_get_params( p_config, &p_caps, &size,
&min_buffers, &max_buffers ))
goto wrong_config;
if( p_caps == NULL )
goto no_caps;
gst_buffer_pool_config_get_allocator( p_config, &p_allocator, ¶ms );
if( p_allocator )
{
if( !GST_IS_VLC_PICTURE_PLANE_ALLOCATOR( p_allocator ))
goto unsupported_allocator;
else
{
if( p_vpool->p_allocator )
gst_object_unref( p_vpool->p_allocator );
p_vpool->p_allocator = gst_object_ref ( p_allocator );
}
}
/* now parse the caps from the config */
if ( !gst_video_info_from_caps( &info, p_caps ))
goto wrong_caps;
/* enable metadata based on config of the pool */
p_vpool->b_add_metavideo =
gst_buffer_pool_config_has_option( p_config,
GST_BUFFER_POOL_OPTION_VIDEO_META );
p_vpool->b_need_aligned =
gst_buffer_pool_config_has_option( p_config,
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT );
if( p_vpool->b_need_aligned )
{
p_vpool->b_add_metavideo = true;
gst_buffer_pool_config_get_video_alignment( p_config, &align );
}
else
gst_video_alignment_reset( &align );
// FIXME: the gst decoders' min buffers may not be equal to the number
// of buffers it actually allocates. Also the max buffers here could
// be zero. Moreover even if it was right, need to check if it can be
// communicated to the vout (including the dpb_size it calculates in
// src/input/decoder.c).
p_vpool->p_dec->i_extra_picture_buffers = 16;
if( !gst_vlc_picture_plane_allocator_query_format( p_vpool->p_allocator,
&info, &align, p_caps))
goto unknown_format;
if( p_vpool->b_need_aligned )
gst_buffer_pool_config_set_video_alignment( p_config, &align);
if( p_vpool->p_caps )
gst_caps_unref( p_vpool->p_caps );
p_vpool->p_caps = gst_caps_ref( p_caps );
p_vpool->info = info;
p_vpool->align = align;
msg_Dbg( p_vpool->p_dec, "setting the following config on the pool: %s, \
size: %lu, min buffers: %u, max buffers: %u", gst_caps_to_string( p_caps ),
info.size, min_buffers, max_buffers );
gst_buffer_pool_config_set_params( p_config, p_caps, info.size,
min_buffers, max_buffers );
return GST_BUFFER_POOL_CLASS (parent_class)->set_config( p_pool, p_config );
/* ERRORS */
wrong_config:
{
msg_Err(p_vpool->p_dec, "wrong pool config" );
return FALSE;
}
no_caps:
{
msg_Err(p_vpool->p_dec, "no input caps in config" );
return FALSE;
}
wrong_caps:
{
msg_Err(p_vpool->p_dec, "invalid caps" );
return FALSE;
}
unknown_format:
{
msg_Err(p_vpool->p_dec, "format unsupported" );
return FALSE;
}
unsupported_allocator:
{
msg_Err(p_vpool->p_dec, "allocator unsupported" );
return FALSE;
}
}
static GstFlowReturn gst_vlc_video_pool_acquire_buffer( GstBufferPool *p_pool,
GstBuffer **p_buffer, GstBufferPoolAcquireParams *p_params )
{
GstVlcVideoPool *p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
GstFlowReturn result;
result = GST_BUFFER_POOL_CLASS( parent_class)->acquire_buffer( p_pool,
p_buffer, p_params );
if( result == GST_FLOW_OK &&
!gst_vlc_picture_plane_allocator_hold( p_vpool->p_allocator,
*p_buffer ))
result = GST_FLOW_EOS;
return result;
}
static void gst_vlc_video_pool_release_buffer( GstBufferPool *p_pool,
GstBuffer *p_buffer )
{
GstVlcVideoPool* p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
gst_vlc_picture_plane_allocator_release( p_vpool->p_allocator, p_buffer );
GST_BUFFER_POOL_CLASS( parent_class )->release_buffer( p_pool, p_buffer );
return;
}
static void gst_vlc_video_pool_free_buffer( GstBufferPool *p_pool,
GstBuffer *p_buffer )
{
GstVlcVideoPool* p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
gst_vlc_picture_plane_allocator_release( p_vpool->p_allocator, p_buffer );
msg_Dbg( p_vpool->p_dec, "freed buffer %p", (void*)p_buffer );
GST_BUFFER_POOL_CLASS( parent_class )->free_buffer( p_pool, p_buffer );
return;
}
static GstFlowReturn gst_vlc_video_pool_alloc_buffer( GstBufferPool *p_pool,
GstBuffer **p_buffer, GstBufferPoolAcquireParams *p_params)
{
VLC_UNUSED( p_params );
GstVlcVideoPool *p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
GstVideoInfo *p_info = &p_vpool->info;
*p_buffer = gst_buffer_new( );
if( !gst_vlc_picture_plane_allocator_alloc( p_vpool->p_allocator,
*p_buffer ))
{
msg_Err( p_vpool->p_dec, "buffer allocation failed" );
return GST_FLOW_EOS;
}
if( p_vpool->b_add_metavideo )
{
msg_Dbg( p_vpool->p_dec, "meta video enabled" );
gst_buffer_add_video_meta_full( *p_buffer, GST_VIDEO_FRAME_FLAG_NONE,
GST_VIDEO_INFO_FORMAT( p_info ), GST_VIDEO_INFO_WIDTH( p_info ),
GST_VIDEO_INFO_HEIGHT( p_info ),
GST_VIDEO_INFO_N_PLANES( p_info ),
p_info->offset, p_info->stride );
}
msg_Dbg( p_vpool->p_dec, "allocated buffer %p", (void*)*p_buffer );
return GST_FLOW_OK;
}
static gboolean gst_vlc_video_pool_start( GstBufferPool *p_pool )
{
GstVlcVideoPool *p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool );
if( !gst_vlc_set_vout_fmt( &p_vpool->info, &p_vpool->align,
p_vpool->p_caps, p_vpool->p_dec ))
return FALSE;
return GST_BUFFER_POOL_CLASS( parent_class )->start( p_pool );
}
static void gst_vlc_video_pool_class_init( GstVlcVideoPoolClass *p_klass )
{
GObjectClass *p_gobject_class = ( GObjectClass* )p_klass;
GstBufferPoolClass *p_gstbufferpool_class = ( GstBufferPoolClass* )p_klass;
p_gobject_class->finalize = gst_vlc_video_pool_finalize;
p_gstbufferpool_class->start = gst_vlc_video_pool_start;
p_gstbufferpool_class->get_options = gst_vlc_video_pool_get_options;
p_gstbufferpool_class->set_config = gst_vlc_video_pool_set_config;
p_gstbufferpool_class->alloc_buffer = gst_vlc_video_pool_alloc_buffer;
p_gstbufferpool_class->free_buffer = gst_vlc_video_pool_free_buffer;
p_gstbufferpool_class->acquire_buffer = gst_vlc_video_pool_acquire_buffer;
p_gstbufferpool_class->release_buffer = gst_vlc_video_pool_release_buffer;
}
static void gst_vlc_video_pool_init( GstVlcVideoPool *p_pool )
{
VLC_UNUSED( p_pool );
}
static void gst_vlc_video_pool_finalize( GObject *p_object )
{
GstVlcVideoPool *p_pool = GST_VLC_VIDEO_POOL_CAST( p_object );
gst_object_unref( p_pool->p_allocator );
G_OBJECT_CLASS( parent_class )->finalize( p_object );
}
GstVlcVideoPool* gst_vlc_video_pool_new(
GstAllocator *p_allocator, decoder_t *p_dec )
{
GstVlcVideoPool *p_pool;
if( !GST_IS_VLC_PICTURE_PLANE_ALLOCATOR( p_allocator ))
{
msg_Err( p_dec, "unsupported allocator for pool" );
return NULL;
}
p_pool = g_object_new( GST_TYPE_VLC_VIDEO_POOL, NULL );
p_pool->p_allocator = gst_object_ref( p_allocator );
p_pool->p_dec = p_dec;
return p_pool;
}
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|