/* FIXME introduce a context ? */
GstBufferPool *pool;
+ GstAllocator *allocator;
+ GstAllocationParams params;
/* parse tracking */
/* input data */
gst_video_codec_state_unref (decoder->priv->output_state);
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;
}
gst_video_decoder_decide_allocation_default (GstVideoDecoder * decoder,
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;
}
GstVideoCodecState *state = decoder->priv->output_state;
GstVideoDecoderClass *klass;
GstQuery *query = NULL;
- GstBufferPool *pool;
- guint size, min, max;
+ GstBufferPool *pool = NULL;
GstAllocator *allocator;
GstAllocationParams params;
- GstStructure *config;
gboolean ret = TRUE;
g_return_val_if_fail (GST_VIDEO_INFO_WIDTH (&state->info) != 0, FALSE);
GST_DEBUG_OBJECT (decoder, "didn't get downstream ALLOCATION hints");
}
- if (klass->decide_allocation) {
- if (!(ret = klass->decide_allocation (decoder, query)))
- goto done;
- }
+ g_assert (klass->decide_allocation != NULL);
+ ret = klass->decide_allocation (decoder, query);
+
+ 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,
* parse them */
if (gst_query_get_n_allocation_params (query) > 0) {
- /* try the allocator */
gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
} else {
allocator = NULL;
gst_allocation_params_init (¶ms);
}
- if (gst_query_get_n_allocation_pools (query) > 0) {
- gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
- size = MAX (size, state->info.size);
- } else {
- pool = NULL;
- size = state->info.size;
- min = max = 0;
- }
-
- 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 ();
+ if (gst_query_get_n_allocation_pools (query) > 0)
+ gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
+ if (!pool) {
+ if (allocator)
+ gst_allocator_unref (allocator);
+ ret = FALSE;
+ goto no_decide_allocation;
}
- /* 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->allocator)
+ gst_allocator_unref (decoder->priv->allocator);
+ decoder->priv->allocator = allocator;
+ decoder->priv->params = params;
if (decoder->priv->pool) {
gst_buffer_pool_set_active (decoder->priv->pool, FALSE);
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
return ret;
+
+ /* Errors */
+no_decide_allocation:
+ {
+ GST_WARNING_OBJECT (decoder, "Subclass failed to decide allocation");
+ goto done;
+ }
}
/**