mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
mpeg2dec: Add stride support
This allow using external pools that have different strides from the default. These strides need to respect certain rules, which we check and if these are not met, we fallback to generic pool. https://bugzilla.gnome.org/show_bug.cgi?id=735379
This commit is contained in:
parent
7e8050728a
commit
35c937f2a4
1 changed files with 74 additions and 13 deletions
|
@ -254,6 +254,25 @@ gst_mpeg2dec_finish (GstVideoDecoder * decoder)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstBufferPool *
|
||||||
|
gst_mpeg2dec_create_generic_pool (GstAllocator * allocator,
|
||||||
|
GstAllocationParams * params, GstCaps * caps, guint size, guint min,
|
||||||
|
guint max, GstStructure ** out_config)
|
||||||
|
{
|
||||||
|
GstBufferPool *pool;
|
||||||
|
GstStructure *config;
|
||||||
|
|
||||||
|
pool = gst_video_buffer_pool_new ();
|
||||||
|
config = gst_buffer_pool_get_config (pool);
|
||||||
|
|
||||||
|
gst_buffer_pool_config_set_allocator (config, allocator, params);
|
||||||
|
gst_buffer_pool_config_set_params (config, caps, size, min, max);
|
||||||
|
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||||
|
|
||||||
|
*out_config = config;
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
{
|
{
|
||||||
|
@ -334,14 +353,9 @@ gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
config = NULL;
|
config = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pool) {
|
if (!pool)
|
||||||
pool = gst_video_buffer_pool_new ();
|
pool = gst_mpeg2dec_create_generic_pool (allocator, ¶ms, caps, size,
|
||||||
config = gst_buffer_pool_get_config (pool);
|
min, max, &config);
|
||||||
gst_buffer_pool_config_set_allocator (config, allocator, ¶ms);
|
|
||||||
gst_buffer_pool_config_set_params (config, caps, size, min, max);
|
|
||||||
gst_buffer_pool_config_add_option (config,
|
|
||||||
GST_BUFFER_POOL_OPTION_VIDEO_META);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_buffer_pool_config_add_option (config,
|
gst_buffer_pool_config_add_option (config,
|
||||||
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
|
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
|
||||||
|
@ -351,7 +365,7 @@ gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
if (allocator)
|
if (allocator)
|
||||||
gst_object_unref (allocator);
|
gst_object_unref (allocator);
|
||||||
|
|
||||||
/* If we are copying out, we'll need to setup and active the other pool */
|
/* If we are copying out, we'll need to setup and activate the other pool */
|
||||||
if (dec->downstream_pool) {
|
if (dec->downstream_pool) {
|
||||||
if (!gst_buffer_pool_set_config (dec->downstream_pool, down_config)) {
|
if (!gst_buffer_pool_set_config (dec->downstream_pool, down_config)) {
|
||||||
down_config = gst_buffer_pool_get_config (dec->downstream_pool);
|
down_config = gst_buffer_pool_get_config (dec->downstream_pool);
|
||||||
|
@ -366,7 +380,7 @@ gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_buffer_pool_set_active (dec->downstream_pool, TRUE))
|
if (!gst_buffer_pool_set_active (dec->downstream_pool, TRUE))
|
||||||
goto pool_activation_failed;
|
goto activate_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now configure the pool, if the pool had made some changes, it will
|
/* Now configure the pool, if the pool had made some changes, it will
|
||||||
|
@ -399,8 +413,48 @@ gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
|
|
||||||
if (!gst_buffer_pool_set_config (pool, config))
|
if (!gst_buffer_pool_set_config (pool, config))
|
||||||
goto config_failed;
|
goto config_failed;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME Activate the pool, and check that strides are uniform */
|
/* For external pools, we need to check strides */
|
||||||
|
if (!GST_IS_VIDEO_BUFFER_POOL (pool) && has_videometa) {
|
||||||
|
GstBuffer *buffer;
|
||||||
|
const GstVideoFormatInfo *finfo;
|
||||||
|
GstVideoMeta *vmeta;
|
||||||
|
gint uv_stride;
|
||||||
|
|
||||||
|
if (!gst_buffer_pool_set_active (pool, TRUE))
|
||||||
|
goto activate_failed;
|
||||||
|
|
||||||
|
if (gst_buffer_pool_acquire_buffer (pool, &buffer, NULL) != GST_FLOW_OK) {
|
||||||
|
gst_buffer_pool_set_active (pool, FALSE);
|
||||||
|
goto acquire_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
vmeta = gst_buffer_get_video_meta (buffer);
|
||||||
|
finfo = gst_video_format_get_info (vmeta->format);
|
||||||
|
|
||||||
|
/* Check that strides are compatible. In this case, we can scale the
|
||||||
|
* stride directly since all the pixel strides for the formats we support
|
||||||
|
* is 1 */
|
||||||
|
uv_stride = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, 1, vmeta->stride[0]);
|
||||||
|
if (uv_stride != vmeta->stride[1] || uv_stride != vmeta->stride[2]) {
|
||||||
|
gst_buffer_pool_set_active (pool, FALSE);
|
||||||
|
gst_object_unref (pool);
|
||||||
|
|
||||||
|
pool = gst_mpeg2dec_create_generic_pool (allocator, ¶ms, caps, size,
|
||||||
|
min, max, &config);
|
||||||
|
|
||||||
|
if (dec->need_alignment) {
|
||||||
|
gst_buffer_pool_config_add_option (config,
|
||||||
|
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
|
||||||
|
gst_buffer_pool_config_set_video_alignment (config, &dec->valign);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic pool don't fail on _set_config() */
|
||||||
|
gst_buffer_pool_set_config (pool, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
||||||
|
@ -415,10 +469,16 @@ config_failed:
|
||||||
("Configuration is most likely invalid, please report this issue."));
|
("Configuration is most likely invalid, please report this issue."));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pool_activation_failed:
|
activate_failed:
|
||||||
gst_object_unref (pool);
|
gst_object_unref (pool);
|
||||||
GST_ELEMENT_ERROR (dec, RESOURCE, SETTINGS,
|
GST_ELEMENT_ERROR (dec, RESOURCE, SETTINGS,
|
||||||
("Failed to activate downstream buffer pool"), (NULL));
|
("Failed to activate buffer pool"), (NULL));
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
acquire_failed:
|
||||||
|
gst_object_unref (pool);
|
||||||
|
GST_ELEMENT_ERROR (dec, RESOURCE, SETTINGS,
|
||||||
|
("Failed to acquire a buffer"), (NULL));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,6 +960,7 @@ handle_picture (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info,
|
||||||
/* Note: We use a non-null 'id' value to make the distinction
|
/* Note: We use a non-null 'id' value to make the distinction
|
||||||
* between the dummy buffers (which have an id of NULL) and the
|
* between the dummy buffers (which have an id of NULL) and the
|
||||||
* ones we did */
|
* ones we did */
|
||||||
|
mpeg2_stride (mpeg2dec->decoder, vframe.info.stride[0]);
|
||||||
mpeg2_set_buf (mpeg2dec->decoder, buf,
|
mpeg2_set_buf (mpeg2dec->decoder, buf,
|
||||||
GINT_TO_POINTER (frame->system_frame_number + 1));
|
GINT_TO_POINTER (frame->system_frame_number + 1));
|
||||||
gst_mpeg2dec_save_buffer (mpeg2dec, frame->system_frame_number, &vframe);
|
gst_mpeg2dec_save_buffer (mpeg2dec, frame->system_frame_number, &vframe);
|
||||||
|
|
Loading…
Reference in a new issue