mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
videoconvert: Support for alternate-field interlacing
Treat the data just like normal data with half the height. Also treat it as progressive when converting from/to I420 because it requires different handling for chroma subsampling. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1027>
This commit is contained in:
parent
0f866832b1
commit
ca4240bd03
2 changed files with 50 additions and 18 deletions
|
@ -1611,10 +1611,12 @@ chain_vscale (GstVideoConverter * convert, GstLineCache * prev, gint idx)
|
||||||
method = GET_OPT_RESAMPLER_METHOD (convert);
|
method = GET_OPT_RESAMPLER_METHOD (convert);
|
||||||
taps = GET_OPT_RESAMPLER_TAPS (convert);
|
taps = GET_OPT_RESAMPLER_TAPS (convert);
|
||||||
|
|
||||||
if (GST_VIDEO_INFO_IS_INTERLACED (&convert->in_info)) {
|
if (GST_VIDEO_INFO_IS_INTERLACED (&convert->in_info)
|
||||||
|
&& (GST_VIDEO_INFO_INTERLACE_MODE (&convert->in_info) !=
|
||||||
|
GST_VIDEO_INTERLACE_MODE_ALTERNATE)) {
|
||||||
convert->v_scaler_i[idx] =
|
convert->v_scaler_i[idx] =
|
||||||
gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_INTERLACED,
|
gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_INTERLACED, taps,
|
||||||
taps, convert->in_height, convert->out_height, convert->config);
|
convert->in_height, convert->out_height, convert->config);
|
||||||
|
|
||||||
gst_video_scaler_get_coeff (convert->v_scaler_i[idx], 0, NULL, &taps_i);
|
gst_video_scaler_get_coeff (convert->v_scaler_i[idx], 0, NULL, &taps_i);
|
||||||
backlog = taps_i;
|
backlog = taps_i;
|
||||||
|
@ -2281,9 +2283,9 @@ gst_video_converter_new_with_pool (const GstVideoInfo * in_info,
|
||||||
gst_video_converter_set_config (convert, config);
|
gst_video_converter_set_config (convert, config);
|
||||||
|
|
||||||
convert->in_maxwidth = GST_VIDEO_INFO_WIDTH (in_info);
|
convert->in_maxwidth = GST_VIDEO_INFO_WIDTH (in_info);
|
||||||
convert->in_maxheight = GST_VIDEO_INFO_HEIGHT (in_info);
|
convert->in_maxheight = GST_VIDEO_INFO_FIELD_HEIGHT (in_info);
|
||||||
convert->out_maxwidth = GST_VIDEO_INFO_WIDTH (out_info);
|
convert->out_maxwidth = GST_VIDEO_INFO_WIDTH (out_info);
|
||||||
convert->out_maxheight = GST_VIDEO_INFO_HEIGHT (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_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_y = get_opt_int (convert, GST_VIDEO_CONVERTER_OPT_SRC_Y, 0);
|
||||||
|
@ -2694,7 +2696,7 @@ gst_video_converter_frame (GstVideoConverter * convert,
|
||||||
GST_VIDEO_FRAME_FORMAT (src)
|
GST_VIDEO_FRAME_FORMAT (src)
|
||||||
|| GST_VIDEO_INFO_WIDTH (&convert->in_info) >
|
|| GST_VIDEO_INFO_WIDTH (&convert->in_info) >
|
||||||
GST_VIDEO_FRAME_WIDTH (src)
|
GST_VIDEO_FRAME_WIDTH (src)
|
||||||
|| GST_VIDEO_INFO_HEIGHT (&convert->in_info) >
|
|| GST_VIDEO_INFO_FIELD_HEIGHT (&convert->in_info) >
|
||||||
GST_VIDEO_FRAME_HEIGHT (src))) {
|
GST_VIDEO_FRAME_HEIGHT (src))) {
|
||||||
g_critical ("Input video frame does not match configuration");
|
g_critical ("Input video frame does not match configuration");
|
||||||
return;
|
return;
|
||||||
|
@ -2703,7 +2705,7 @@ gst_video_converter_frame (GstVideoConverter * convert,
|
||||||
GST_VIDEO_FRAME_FORMAT (dest)
|
GST_VIDEO_FRAME_FORMAT (dest)
|
||||||
|| GST_VIDEO_INFO_WIDTH (&convert->out_info) >
|
|| GST_VIDEO_INFO_WIDTH (&convert->out_info) >
|
||||||
GST_VIDEO_FRAME_WIDTH (dest)
|
GST_VIDEO_FRAME_WIDTH (dest)
|
||||||
|| GST_VIDEO_INFO_HEIGHT (&convert->out_info) >
|
|| GST_VIDEO_INFO_FIELD_HEIGHT (&convert->out_info) >
|
||||||
GST_VIDEO_FRAME_HEIGHT (dest))) {
|
GST_VIDEO_FRAME_HEIGHT (dest))) {
|
||||||
g_critical ("Output video frame does not match configuration");
|
g_critical ("Output video frame does not match configuration");
|
||||||
return;
|
return;
|
||||||
|
@ -2753,7 +2755,9 @@ video_converter_compute_resample (GstVideoConverter * convert, gint idx)
|
||||||
in_info->chroma_site != out_info->chroma_site ||
|
in_info->chroma_site != out_info->chroma_site ||
|
||||||
in_info->width != out_info->width ||
|
in_info->width != out_info->width ||
|
||||||
in_info->height != out_info->height) {
|
in_info->height != out_info->height) {
|
||||||
if (GST_VIDEO_INFO_IS_INTERLACED (in_info)) {
|
if (GST_VIDEO_INFO_IS_INTERLACED (in_info)
|
||||||
|
&& GST_VIDEO_INFO_INTERLACE_MODE (in_info) !=
|
||||||
|
GST_VIDEO_INTERLACE_MODE_ALTERNATE) {
|
||||||
if (!CHECK_CHROMA_DOWNSAMPLE (convert))
|
if (!CHECK_CHROMA_DOWNSAMPLE (convert))
|
||||||
convert->upsample_i[idx] = gst_video_chroma_resample_new (0,
|
convert->upsample_i[idx] = gst_video_chroma_resample_new (0,
|
||||||
in_info->chroma_site, GST_VIDEO_CHROMA_FLAG_INTERLACED,
|
in_info->chroma_site, GST_VIDEO_CHROMA_FLAG_INTERLACED,
|
||||||
|
@ -3309,7 +3313,9 @@ convert_I420_YUY2 (GstVideoConverter * convert, const GstVideoFrame * src,
|
||||||
int i;
|
int i;
|
||||||
gint width = convert->in_width;
|
gint width = convert->in_width;
|
||||||
gint height = convert->in_height;
|
gint height = convert->in_height;
|
||||||
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
|
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src)
|
||||||
|
&& (GST_VIDEO_INFO_INTERLACE_MODE (&src->info) !=
|
||||||
|
GST_VIDEO_INTERLACE_MODE_ALTERNATE);
|
||||||
gint h2;
|
gint h2;
|
||||||
FConvertTask *tasks;
|
FConvertTask *tasks;
|
||||||
FConvertTask **tasks_p;
|
FConvertTask **tasks_p;
|
||||||
|
@ -3382,7 +3388,9 @@ convert_I420_UYVY (GstVideoConverter * convert, const GstVideoFrame * src,
|
||||||
int i;
|
int i;
|
||||||
gint width = convert->in_width;
|
gint width = convert->in_width;
|
||||||
gint height = convert->in_height;
|
gint height = convert->in_height;
|
||||||
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
|
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src)
|
||||||
|
&& (GST_VIDEO_INFO_INTERLACE_MODE (&src->info) !=
|
||||||
|
GST_VIDEO_INTERLACE_MODE_ALTERNATE);
|
||||||
gint h2;
|
gint h2;
|
||||||
FConvertTask *tasks;
|
FConvertTask *tasks;
|
||||||
FConvertTask **tasks_p;
|
FConvertTask **tasks_p;
|
||||||
|
@ -3455,7 +3463,9 @@ convert_I420_AYUV (GstVideoConverter * convert, const GstVideoFrame * src,
|
||||||
int i;
|
int i;
|
||||||
gint width = convert->in_width;
|
gint width = convert->in_width;
|
||||||
gint height = convert->in_height;
|
gint height = convert->in_height;
|
||||||
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
|
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src)
|
||||||
|
&& (GST_VIDEO_INFO_INTERLACE_MODE (&src->info) !=
|
||||||
|
GST_VIDEO_INTERLACE_MODE_ALTERNATE);
|
||||||
guint8 alpha = MIN (convert->alpha_value, 255);
|
guint8 alpha = MIN (convert->alpha_value, 255);
|
||||||
gint h2;
|
gint h2;
|
||||||
FConvertTask *tasks;
|
FConvertTask *tasks;
|
||||||
|
@ -3533,7 +3543,9 @@ convert_YUY2_I420 (GstVideoConverter * convert, const GstVideoFrame * src,
|
||||||
int i;
|
int i;
|
||||||
gint width = convert->in_width;
|
gint width = convert->in_width;
|
||||||
gint height = convert->in_height;
|
gint height = convert->in_height;
|
||||||
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
|
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src)
|
||||||
|
&& (GST_VIDEO_INFO_INTERLACE_MODE (&src->info) !=
|
||||||
|
GST_VIDEO_INTERLACE_MODE_ALTERNATE);
|
||||||
gint h2;
|
gint h2;
|
||||||
FConvertTask *tasks;
|
FConvertTask *tasks;
|
||||||
FConvertTask **tasks_p;
|
FConvertTask **tasks_p;
|
||||||
|
@ -3692,7 +3704,9 @@ convert_v210_I420 (GstVideoConverter * convert, const GstVideoFrame * src,
|
||||||
int i;
|
int i;
|
||||||
gint width = convert->in_width;
|
gint width = convert->in_width;
|
||||||
gint height = convert->in_height;
|
gint height = convert->in_height;
|
||||||
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
|
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src)
|
||||||
|
&& (GST_VIDEO_INFO_INTERLACE_MODE (&src->info) !=
|
||||||
|
GST_VIDEO_INTERLACE_MODE_ALTERNATE);
|
||||||
gint h2;
|
gint h2;
|
||||||
FConvertTask *tasks;
|
FConvertTask *tasks;
|
||||||
FConvertTask **tasks_p;
|
FConvertTask **tasks_p;
|
||||||
|
@ -4075,7 +4089,9 @@ convert_UYVY_I420 (GstVideoConverter * convert, const GstVideoFrame * src,
|
||||||
int i;
|
int i;
|
||||||
gint width = convert->in_width;
|
gint width = convert->in_width;
|
||||||
gint height = convert->in_height;
|
gint height = convert->in_height;
|
||||||
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
|
gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src)
|
||||||
|
&& (GST_VIDEO_INFO_INTERLACE_MODE (&src->info) !=
|
||||||
|
GST_VIDEO_INTERLACE_MODE_ALTERNATE);
|
||||||
gint h2;
|
gint h2;
|
||||||
FConvertTask *tasks;
|
FConvertTask *tasks;
|
||||||
FConvertTask **tasks_p;
|
FConvertTask **tasks_p;
|
||||||
|
@ -6519,7 +6535,9 @@ setup_scale (GstVideoConverter * convert)
|
||||||
|
|
||||||
n_planes = GST_VIDEO_INFO_N_PLANES (out_info);
|
n_planes = GST_VIDEO_INFO_N_PLANES (out_info);
|
||||||
|
|
||||||
interlaced = GST_VIDEO_INFO_IS_INTERLACED (&convert->in_info);
|
interlaced = GST_VIDEO_INFO_IS_INTERLACED (&convert->in_info)
|
||||||
|
&& GST_VIDEO_INFO_INTERLACE_MODE (&convert->in_info) !=
|
||||||
|
GST_VIDEO_INTERLACE_MODE_ALTERNATE;
|
||||||
|
|
||||||
method = GET_OPT_RESAMPLER_METHOD (convert);
|
method = GET_OPT_RESAMPLER_METHOD (convert);
|
||||||
if (method == GST_VIDEO_RESAMPLER_METHOD_NEAREST)
|
if (method == GST_VIDEO_RESAMPLER_METHOD_NEAREST)
|
||||||
|
@ -7247,7 +7265,7 @@ video_converter_lookup_fastpath (GstVideoConverter * convert)
|
||||||
guint in_bpp, out_bpp;
|
guint in_bpp, out_bpp;
|
||||||
|
|
||||||
width = GST_VIDEO_INFO_WIDTH (&convert->in_info);
|
width = GST_VIDEO_INFO_WIDTH (&convert->in_info);
|
||||||
height = GST_VIDEO_INFO_HEIGHT (&convert->in_info);
|
height = GST_VIDEO_INFO_FIELD_HEIGHT (&convert->in_info);
|
||||||
|
|
||||||
if (GET_OPT_DITHER_QUANTIZATION (convert) != 1)
|
if (GET_OPT_DITHER_QUANTIZATION (convert) != 1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -111,6 +111,9 @@ static gboolean gst_video_convert_set_info (GstVideoFilter * filter,
|
||||||
static GstFlowReturn gst_video_convert_transform_frame (GstVideoFilter * filter,
|
static GstFlowReturn gst_video_convert_transform_frame (GstVideoFilter * filter,
|
||||||
GstVideoFrame * in_frame, GstVideoFrame * out_frame);
|
GstVideoFrame * in_frame, GstVideoFrame * out_frame);
|
||||||
|
|
||||||
|
static GstCapsFeatures *features_format_interlaced,
|
||||||
|
*features_format_interlaced_sysmem;
|
||||||
|
|
||||||
/* copies the given caps */
|
/* copies the given caps */
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_video_convert_caps_remove_format_info (GstCaps * caps)
|
gst_video_convert_caps_remove_format_info (GstCaps * caps)
|
||||||
|
@ -135,10 +138,14 @@ gst_video_convert_caps_remove_format_info (GstCaps * caps)
|
||||||
st = gst_structure_copy (st);
|
st = gst_structure_copy (st);
|
||||||
/* Only remove format info for the cases when we can actually convert */
|
/* Only remove format info for the cases when we can actually convert */
|
||||||
if (!gst_caps_features_is_any (f)
|
if (!gst_caps_features_is_any (f)
|
||||||
&& gst_caps_features_is_equal (f,
|
&& (gst_caps_features_is_equal (f,
|
||||||
GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))
|
GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
|
||||||
|
|| gst_caps_features_is_equal (f, features_format_interlaced)
|
||||||
|
|| gst_caps_features_is_equal (f,
|
||||||
|
features_format_interlaced_sysmem))) {
|
||||||
gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site",
|
gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site",
|
||||||
NULL);
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
gst_caps_append_structure_full (res, st, gst_caps_features_copy (f));
|
gst_caps_append_structure_full (res, st, gst_caps_features_copy (f));
|
||||||
}
|
}
|
||||||
|
@ -743,6 +750,13 @@ plugin_init (GstPlugin * plugin)
|
||||||
|
|
||||||
_colorspace_quark = g_quark_from_static_string ("colorspace");
|
_colorspace_quark = g_quark_from_static_string ("colorspace");
|
||||||
|
|
||||||
|
features_format_interlaced =
|
||||||
|
gst_caps_features_new (GST_CAPS_FEATURE_FORMAT_INTERLACED, NULL);
|
||||||
|
features_format_interlaced_sysmem =
|
||||||
|
gst_caps_features_copy (features_format_interlaced);
|
||||||
|
gst_caps_features_add (features_format_interlaced_sysmem,
|
||||||
|
GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY);
|
||||||
|
|
||||||
return gst_element_register (plugin, "videoconvert",
|
return gst_element_register (plugin, "videoconvert",
|
||||||
GST_RANK_NONE, GST_TYPE_VIDEO_CONVERT);
|
GST_RANK_NONE, GST_TYPE_VIDEO_CONVERT);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue