video-converter: Fix set config not having effect after start

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6594>
This commit is contained in:
Sanchayan Maity 2024-02-07 22:13:37 +05:30 committed by GStreamer Marge Bot
parent a6c8c6f866
commit a9c4289da7
2 changed files with 115 additions and 48 deletions

View file

@ -2292,61 +2292,17 @@ convert_get_alpha_mode (GstVideoConverter * convert)
return ALPHA_MODE_SET;
}
/**
* gst_video_converter_new_with_pool: (skip)
* @in_info: a #GstVideoInfo
* @out_info: a #GstVideoInfo
* @config: (transfer full): a #GstStructure with configuration options
* @pool: (nullable): a #GstTaskPool to spawn threads from
*
* Create a new converter object to convert between @in_info and @out_info
* with @config.
*
* The optional @pool can be used to spawn threads, this is useful when
* creating new converters rapidly, for example when updating cropping.
*
* Returns (nullable): a #GstVideoConverter or %NULL if conversion is not possible.
*
* Since: 1.20
*/
GstVideoConverter *
gst_video_converter_new_with_pool (const GstVideoInfo * in_info,
const GstVideoInfo * out_info, GstStructure * config, GstTaskPool * pool)
static void
gst_video_converter_init_from_config (GstVideoConverter * convert)
{
GstVideoConverter *convert;
GstLineCache *prev;
const GstVideoFormatInfo *fin, *fout, *finfo;
GstVideoInfo *in_info = &convert->in_info;
GstVideoInfo *out_info = &convert->out_info;
gdouble alpha_value;
gint n_threads, i;
gboolean async_tasks;
g_return_val_if_fail (in_info != NULL, NULL);
g_return_val_if_fail (out_info != NULL, NULL);
/* we won't ever do framerate conversion */
g_return_val_if_fail (in_info->fps_n == out_info->fps_n, NULL);
g_return_val_if_fail (in_info->fps_d == out_info->fps_d, NULL);
/* we won't ever do deinterlace */
g_return_val_if_fail (in_info->interlace_mode == out_info->interlace_mode,
NULL);
convert = g_new0 (GstVideoConverter, 1);
fin = in_info->finfo;
fout = out_info->finfo;
convert->in_info = *in_info;
convert->out_info = *out_info;
/* default config */
convert->config = gst_structure_new_empty ("GstVideoConverter");
if (config)
gst_video_converter_set_config (convert, config);
convert->in_maxwidth = GST_VIDEO_INFO_WIDTH (in_info);
convert->in_maxheight = GST_VIDEO_INFO_FIELD_HEIGHT (in_info);
convert->out_maxwidth = GST_VIDEO_INFO_WIDTH (out_info);
convert->out_maxheight = GST_VIDEO_INFO_FIELD_HEIGHT (out_info);
convert->in_x = get_opt_int (convert, GST_VIDEO_CONVERTER_OPT_SRC_X, 0);
convert->in_y = get_opt_int (convert, GST_VIDEO_CONVERTER_OPT_SRC_Y, 0);
convert->in_x &= ~((1 << fin->w_sub[1]) - 1);
@ -2438,6 +2394,58 @@ gst_video_converter_new_with_pool (const GstVideoInfo * in_info,
out_info->colorimetry.matrix);
convert->out_info.colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
}
}
/**
* gst_video_converter_new_with_pool: (skip)
* @in_info: a #GstVideoInfo
* @out_info: a #GstVideoInfo
* @config: (transfer full): a #GstStructure with configuration options
* @pool: (nullable): a #GstTaskPool to spawn threads from
*
* Create a new converter object to convert between @in_info and @out_info
* with @config.
*
* The optional @pool can be used to spawn threads, this is useful when
* creating new converters rapidly, for example when updating cropping.
*
* Returns (nullable): a #GstVideoConverter or %NULL if conversion is not possible.
*
* Since: 1.20
*/
GstVideoConverter *
gst_video_converter_new_with_pool (const GstVideoInfo * in_info,
const GstVideoInfo * out_info, GstStructure * config, GstTaskPool * pool)
{
GstVideoConverter *convert;
GstLineCache *prev;
gint n_threads, i;
gboolean async_tasks;
g_return_val_if_fail (in_info != NULL, NULL);
g_return_val_if_fail (out_info != NULL, NULL);
/* we won't ever do framerate conversion */
g_return_val_if_fail (in_info->fps_n == out_info->fps_n, NULL);
g_return_val_if_fail (in_info->fps_d == out_info->fps_d, NULL);
/* we won't ever do deinterlace */
g_return_val_if_fail (in_info->interlace_mode == out_info->interlace_mode,
NULL);
convert = g_new0 (GstVideoConverter, 1);
convert->in_info = *in_info;
convert->out_info = *out_info;
convert->in_maxwidth = GST_VIDEO_INFO_WIDTH (in_info);
convert->in_maxheight = GST_VIDEO_INFO_FIELD_HEIGHT (in_info);
convert->out_maxwidth = GST_VIDEO_INFO_WIDTH (out_info);
convert->out_maxheight = GST_VIDEO_INFO_FIELD_HEIGHT (out_info);
convert->config = gst_structure_new_empty ("GstVideoConverter");
if (config)
gst_video_converter_set_config (convert, config);
else
gst_video_converter_init_from_config (convert);
n_threads = get_opt_uint (convert, GST_VIDEO_CONVERTER_OPT_THREADS, 1);
if (n_threads == 0 || n_threads > g_get_num_processors ())
@ -2718,6 +2726,8 @@ gst_video_converter_set_config (GstVideoConverter * convert,
gst_structure_foreach (config, copy_config, convert);
gst_structure_free (config);
gst_video_converter_init_from_config (convert);
return TRUE;
}

View file

@ -2816,6 +2816,62 @@ GST_START_TEST (test_video_convert)
GST_END_TEST;
GST_START_TEST (test_video_convert_with_config_update)
{
GstVideoInfo ininfo, outinfo;
GstVideoFrame inframe, outframe;
GstBuffer *inbuffer, *outbuffer;
GstVideoConverter *convert;
fail_unless (gst_video_info_set_format (&ininfo, GST_VIDEO_FORMAT_ARGB, 320,
240));
inbuffer = gst_buffer_new_and_alloc (ininfo.size);
gst_buffer_memset (inbuffer, 0, 0, -1);
gst_video_frame_map (&inframe, &ininfo, inbuffer, GST_MAP_READ);
fail_unless (gst_video_info_set_format (&outinfo, GST_VIDEO_FORMAT_BGRx, 400,
300));
outbuffer = gst_buffer_new_and_alloc (outinfo.size);
gst_video_frame_map (&outframe, &outinfo, outbuffer, GST_MAP_WRITE);
convert = gst_video_converter_new (&ininfo, &outinfo,
gst_structure_new ("options",
GST_VIDEO_CONVERTER_OPT_RESAMPLER_METHOD,
GST_TYPE_VIDEO_RESAMPLER_METHOD, 3,
GST_VIDEO_CONVERTER_OPT_SRC_X, G_TYPE_INT, 10,
GST_VIDEO_CONVERTER_OPT_SRC_Y, G_TYPE_INT, 0,
GST_VIDEO_CONVERTER_OPT_SRC_WIDTH, G_TYPE_INT, 300,
GST_VIDEO_CONVERTER_OPT_SRC_HEIGHT, G_TYPE_INT, 220,
GST_VIDEO_CONVERTER_OPT_DEST_X, G_TYPE_INT, 80,
GST_VIDEO_CONVERTER_OPT_DEST_Y, G_TYPE_INT, 60,
GST_VIDEO_CONVERTER_OPT_DEST_WIDTH, G_TYPE_INT, 300,
GST_VIDEO_CONVERTER_OPT_DEST_HEIGHT, G_TYPE_INT, 220, NULL));
g_assert (gst_video_info_is_equal (&ininfo,
gst_video_converter_get_in_info (convert)));
g_assert (gst_video_info_is_equal (&outinfo,
gst_video_converter_get_out_info (convert)));
gst_video_converter_frame (convert, &inframe, &outframe);
GstStructure *options = gst_structure_new ("options",
GST_VIDEO_CONVERTER_OPT_DEST_WIDTH, G_TYPE_INT, 220,
GST_VIDEO_CONVERTER_OPT_DEST_HEIGHT, G_TYPE_INT, 300, NULL);
gst_video_converter_set_config (convert, options);
gst_video_converter_frame (convert, &inframe, &outframe);
gst_video_converter_free (convert);
gst_video_frame_unmap (&outframe);
gst_buffer_unref (outbuffer);
gst_video_frame_unmap (&inframe);
gst_buffer_unref (inbuffer);
}
GST_END_TEST;
GST_START_TEST (test_video_convert_multithreading)
{
GstVideoInfo ininfo, outinfo;
@ -4338,6 +4394,7 @@ video_suite (void)
tcase_add_test (tc_chain, test_video_color_primaries_equivalent);
tcase_add_test (tc_chain, test_info_dma_drm);
tcase_add_test (tc_chain, test_video_meta_serialize);
tcase_add_test (tc_chain, test_video_convert_with_config_update);
return s;
}