diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c b/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c index 435c7a2b58..ae5f62d852 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c @@ -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; } diff --git a/subprojects/gst-plugins-base/tests/check/libs/video.c b/subprojects/gst-plugins-base/tests/check/libs/video.c index 7509e83909..939f9d8dee 100644 --- a/subprojects/gst-plugins-base/tests/check/libs/video.c +++ b/subprojects/gst-plugins-base/tests/check/libs/video.c @@ -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; }