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 ); }
static gboolean gst_vlc_video_sink_propose_allocation( GstBaseSink* p_bsink, GstQuery* p_query ) { GstVlcVideoSink *p_vsink = GST_VLC_VIDEO_SINK( p_bsink ); GstCaps *p_caps; gboolean b_need_pool; GstBufferPool* p_pool = NULL; gsize i_size; gst_query_parse_allocation (p_query, &p_caps, &b_need_pool); if( p_caps == NULL ) goto no_caps; if( b_need_pool ) { GstVideoInfo info; if( !gst_video_info_from_caps( &info, p_caps )) goto invalid_caps; p_pool = (GstBufferPool*) gst_vlc_video_sink_create_pool( p_vsink, p_caps, info.size, 2 ); if( p_pool == NULL ) goto no_pool; i_size = GST_VIDEO_INFO_SIZE( &GST_VLC_VIDEO_POOL_CAST( p_pool )->info); } if( p_pool ) { /* we need at least 2 buffer because we hold on to the last one */ gst_query_add_allocation_pool( p_query, p_pool, i_size, 2, 0); gst_object_unref (p_pool); } /* we support various metadata */ gst_query_add_allocation_meta( p_query, GST_VIDEO_META_API_TYPE, NULL ); return TRUE; /* ERRORS */ no_pool: { msg_Err( p_vsink->p_dec, "failed to create the pool" ); return FALSE; } no_caps: { msg_Err( p_vsink->p_dec, "no caps in allocation query" ); return FALSE; } invalid_caps: { msg_Err( p_vsink->p_dec, "invalid caps in allocation query" ); return FALSE; } }
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 ); GST_BUFFER_POOL_CLASS( parent_class )->free_buffer( p_pool, p_buffer ); return; }
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 ); GstVideoInfo *p_info; 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 GstFlowReturn gst_vlc_video_pool_alloc_buffer( GstBufferPool *p_pool, GstBuffer **p_buffer, GstBufferPoolAcquireParams *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 )) 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 ); } return GST_FLOW_OK; }
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; 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 ); if( !gst_vlc_picture_plane_allocator_query_format( p_vpool->p_allocator, &info, p_caps)) goto unknown_format; 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; 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; } }