videodecoder: Do bufferpool configuration inside the default decide_allocation() implementation
This allows subclasses to override it, as is necessary for e.g. the video-crop meta. It is now necessary that after decide_allocation() there is always a allocator and a configured buffer pool inside the query.
This commit is contained in:
parent
7736044d45
commit
cb04d8e003
@ -162,6 +162,8 @@ struct _GstVideoDecoderPrivate
|
|||||||
/* FIXME introduce a context ? */
|
/* FIXME introduce a context ? */
|
||||||
|
|
||||||
GstBufferPool *pool;
|
GstBufferPool *pool;
|
||||||
|
GstAllocator *allocator;
|
||||||
|
GstAllocationParams params;
|
||||||
|
|
||||||
/* parse tracking */
|
/* parse tracking */
|
||||||
/* input data */
|
/* input data */
|
||||||
@ -639,7 +641,12 @@ gst_video_decoder_finalize (GObject * object)
|
|||||||
gst_video_codec_state_unref (decoder->priv->output_state);
|
gst_video_codec_state_unref (decoder->priv->output_state);
|
||||||
|
|
||||||
if (decoder->priv->pool) {
|
if (decoder->priv->pool) {
|
||||||
g_object_unref (decoder->priv->pool);
|
gst_object_unref (decoder->priv->pool);
|
||||||
|
decoder->priv->pool = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoder->priv->allocator) {
|
||||||
|
gst_allocator_unref (decoder->priv->allocator);
|
||||||
decoder->priv->pool = NULL;
|
decoder->priv->pool = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2355,6 +2362,70 @@ static gboolean
|
|||||||
gst_video_decoder_decide_allocation_default (GstVideoDecoder * decoder,
|
gst_video_decoder_decide_allocation_default (GstVideoDecoder * decoder,
|
||||||
GstQuery * query)
|
GstQuery * query)
|
||||||
{
|
{
|
||||||
|
GstCaps *outcaps;
|
||||||
|
GstBufferPool *pool = NULL;
|
||||||
|
guint size, min, max;
|
||||||
|
GstAllocator *allocator = NULL;
|
||||||
|
GstAllocationParams params;
|
||||||
|
GstStructure *config;
|
||||||
|
gboolean update_pool, update_allocator;
|
||||||
|
GstVideoInfo vinfo;
|
||||||
|
|
||||||
|
gst_query_parse_allocation (query, &outcaps, NULL);
|
||||||
|
gst_video_info_init (&vinfo);
|
||||||
|
gst_video_info_from_caps (&vinfo, outcaps);
|
||||||
|
|
||||||
|
/* we got configuration from our peer or the decide_allocation method,
|
||||||
|
* parse them */
|
||||||
|
if (gst_query_get_n_allocation_params (query) > 0) {
|
||||||
|
/* try the allocator */
|
||||||
|
gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
|
||||||
|
update_allocator = TRUE;
|
||||||
|
} else {
|
||||||
|
allocator = NULL;
|
||||||
|
gst_allocation_params_init (¶ms);
|
||||||
|
update_allocator = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_query_get_n_allocation_pools (query) > 0) {
|
||||||
|
gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
|
||||||
|
size = MAX (size, vinfo.size);
|
||||||
|
update_pool = TRUE;
|
||||||
|
} else {
|
||||||
|
pool = NULL;
|
||||||
|
size = vinfo.size;
|
||||||
|
min = max = 0;
|
||||||
|
|
||||||
|
update_pool = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pool == NULL) {
|
||||||
|
/* no pool, we can make our own */
|
||||||
|
GST_DEBUG_OBJECT (decoder, "no pool, making new pool");
|
||||||
|
pool = gst_video_buffer_pool_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now configure */
|
||||||
|
config = gst_buffer_pool_get_config (pool);
|
||||||
|
gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
|
||||||
|
gst_buffer_pool_config_set_allocator (config, allocator, ¶ms);
|
||||||
|
gst_buffer_pool_set_config (pool, config);
|
||||||
|
|
||||||
|
if (update_allocator)
|
||||||
|
gst_query_set_nth_allocation_param (query, 0, allocator, ¶ms);
|
||||||
|
else
|
||||||
|
gst_query_add_allocation_param (query, allocator, ¶ms);
|
||||||
|
if (allocator)
|
||||||
|
gst_allocator_unref (allocator);
|
||||||
|
|
||||||
|
if (update_pool)
|
||||||
|
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
||||||
|
else
|
||||||
|
gst_query_add_allocation_pool (query, pool, size, min, max);
|
||||||
|
|
||||||
|
if (pool)
|
||||||
|
gst_object_unref (pool);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2374,11 +2445,9 @@ gst_video_decoder_set_src_caps (GstVideoDecoder * decoder)
|
|||||||
GstVideoCodecState *state = decoder->priv->output_state;
|
GstVideoCodecState *state = decoder->priv->output_state;
|
||||||
GstVideoDecoderClass *klass;
|
GstVideoDecoderClass *klass;
|
||||||
GstQuery *query = NULL;
|
GstQuery *query = NULL;
|
||||||
GstBufferPool *pool;
|
GstBufferPool *pool = NULL;
|
||||||
guint size, min, max;
|
|
||||||
GstAllocator *allocator;
|
GstAllocator *allocator;
|
||||||
GstAllocationParams params;
|
GstAllocationParams params;
|
||||||
GstStructure *config;
|
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_VIDEO_INFO_WIDTH (&state->info) != 0, FALSE);
|
g_return_val_if_fail (GST_VIDEO_INFO_WIDTH (&state->info) != 0, FALSE);
|
||||||
@ -2409,41 +2478,37 @@ gst_video_decoder_set_src_caps (GstVideoDecoder * decoder)
|
|||||||
GST_DEBUG_OBJECT (decoder, "didn't get downstream ALLOCATION hints");
|
GST_DEBUG_OBJECT (decoder, "didn't get downstream ALLOCATION hints");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (klass->decide_allocation) {
|
g_assert (klass->decide_allocation != NULL);
|
||||||
if (!(ret = klass->decide_allocation (decoder, query)))
|
ret = klass->decide_allocation (decoder, query);
|
||||||
goto done;
|
|
||||||
}
|
GST_DEBUG_OBJECT (decoder, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, ret,
|
||||||
|
query);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
goto no_decide_allocation;
|
||||||
|
|
||||||
/* we got configuration from our peer or the decide_allocation method,
|
/* we got configuration from our peer or the decide_allocation method,
|
||||||
* parse them */
|
* parse them */
|
||||||
if (gst_query_get_n_allocation_params (query) > 0) {
|
if (gst_query_get_n_allocation_params (query) > 0) {
|
||||||
/* try the allocator */
|
|
||||||
gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
|
gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
|
||||||
} else {
|
} else {
|
||||||
allocator = NULL;
|
allocator = NULL;
|
||||||
gst_allocation_params_init (¶ms);
|
gst_allocation_params_init (¶ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gst_query_get_n_allocation_pools (query) > 0) {
|
if (gst_query_get_n_allocation_pools (query) > 0)
|
||||||
gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
|
gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
|
||||||
size = MAX (size, state->info.size);
|
if (!pool) {
|
||||||
} else {
|
if (allocator)
|
||||||
pool = NULL;
|
gst_allocator_unref (allocator);
|
||||||
size = state->info.size;
|
ret = FALSE;
|
||||||
min = max = 0;
|
goto no_decide_allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pool == NULL) {
|
if (decoder->priv->allocator)
|
||||||
/* no pool, we can make our own */
|
gst_allocator_unref (decoder->priv->allocator);
|
||||||
GST_DEBUG_OBJECT (decoder, "no pool, making new pool");
|
decoder->priv->allocator = allocator;
|
||||||
pool = gst_video_buffer_pool_new ();
|
decoder->priv->params = params;
|
||||||
}
|
|
||||||
|
|
||||||
/* now configure */
|
|
||||||
config = gst_buffer_pool_get_config (pool);
|
|
||||||
gst_buffer_pool_config_set_params (config, state->caps, size, min, max);
|
|
||||||
gst_buffer_pool_config_set_allocator (config, allocator, ¶ms);
|
|
||||||
gst_buffer_pool_set_config (pool, config);
|
|
||||||
|
|
||||||
if (decoder->priv->pool) {
|
if (decoder->priv->pool) {
|
||||||
gst_buffer_pool_set_active (decoder->priv->pool, FALSE);
|
gst_buffer_pool_set_active (decoder->priv->pool, FALSE);
|
||||||
@ -2461,6 +2526,13 @@ done:
|
|||||||
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* Errors */
|
||||||
|
no_decide_allocation:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (decoder, "Subclass failed to decide allocation");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user