Skip to content

Commit

Permalink
videoconvert: Support for alternate-field interlacing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
vivia committed Feb 4, 2021
1 parent 0f86683 commit ca4240b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 18 deletions.
50 changes: 34 additions & 16 deletions gst-libs/gst/video/video-converter.c
Expand Up @@ -1611,10 +1611,12 @@ chain_vscale (GstVideoConverter * convert, GstLineCache * prev, gint idx)
method = GET_OPT_RESAMPLER_METHOD (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] =
gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_INTERLACED,
taps, convert->in_height, convert->out_height, convert->config);
gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_INTERLACED, taps,
convert->in_height, convert->out_height, convert->config);

gst_video_scaler_get_coeff (convert->v_scaler_i[idx], 0, NULL, &taps_i);
backlog = taps_i;
Expand Down Expand Up @@ -2281,9 +2283,9 @@ gst_video_converter_new_with_pool (const GstVideoInfo * in_info,
gst_video_converter_set_config (convert, config);

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_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_y = get_opt_int (convert, GST_VIDEO_CONVERTER_OPT_SRC_Y, 0);
Expand Down Expand Up @@ -2694,7 +2696,7 @@ gst_video_converter_frame (GstVideoConverter * convert,
GST_VIDEO_FRAME_FORMAT (src)
|| GST_VIDEO_INFO_WIDTH (&convert->in_info) >
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))) {
g_critical ("Input video frame does not match configuration");
return;
Expand All @@ -2703,7 +2705,7 @@ gst_video_converter_frame (GstVideoConverter * convert,
GST_VIDEO_FRAME_FORMAT (dest)
|| GST_VIDEO_INFO_WIDTH (&convert->out_info) >
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))) {
g_critical ("Output video frame does not match configuration");
return;
Expand Down Expand Up @@ -2753,7 +2755,9 @@ video_converter_compute_resample (GstVideoConverter * convert, gint idx)
in_info->chroma_site != out_info->chroma_site ||
in_info->width != out_info->width ||
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))
convert->upsample_i[idx] = gst_video_chroma_resample_new (0,
in_info->chroma_site, GST_VIDEO_CHROMA_FLAG_INTERLACED,
Expand Down Expand Up @@ -3309,7 +3313,9 @@ convert_I420_YUY2 (GstVideoConverter * convert, const GstVideoFrame * src,
int i;
gint width = convert->in_width;
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;
FConvertTask *tasks;
FConvertTask **tasks_p;
Expand Down Expand Up @@ -3382,7 +3388,9 @@ convert_I420_UYVY (GstVideoConverter * convert, const GstVideoFrame * src,
int i;
gint width = convert->in_width;
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;
FConvertTask *tasks;
FConvertTask **tasks_p;
Expand Down Expand Up @@ -3455,7 +3463,9 @@ convert_I420_AYUV (GstVideoConverter * convert, const GstVideoFrame * src,
int i;
gint width = convert->in_width;
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);
gint h2;
FConvertTask *tasks;
Expand Down Expand Up @@ -3533,7 +3543,9 @@ convert_YUY2_I420 (GstVideoConverter * convert, const GstVideoFrame * src,
int i;
gint width = convert->in_width;
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;
FConvertTask *tasks;
FConvertTask **tasks_p;
Expand Down Expand Up @@ -3692,7 +3704,9 @@ convert_v210_I420 (GstVideoConverter * convert, const GstVideoFrame * src,
int i;
gint width = convert->in_width;
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;
FConvertTask *tasks;
FConvertTask **tasks_p;
Expand Down Expand Up @@ -4075,7 +4089,9 @@ convert_UYVY_I420 (GstVideoConverter * convert, const GstVideoFrame * src,
int i;
gint width = convert->in_width;
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;
FConvertTask *tasks;
FConvertTask **tasks_p;
Expand Down Expand Up @@ -6519,7 +6535,9 @@ setup_scale (GstVideoConverter * convert)

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);
if (method == GST_VIDEO_RESAMPLER_METHOD_NEAREST)
Expand Down Expand Up @@ -7247,7 +7265,7 @@ video_converter_lookup_fastpath (GstVideoConverter * convert)
guint in_bpp, out_bpp;

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)
return FALSE;
Expand Down
18 changes: 16 additions & 2 deletions gst/videoconvert/gstvideoconvert.c
Expand Up @@ -111,6 +111,9 @@ static gboolean gst_video_convert_set_info (GstVideoFilter * filter,
static GstFlowReturn gst_video_convert_transform_frame (GstVideoFilter * filter,
GstVideoFrame * in_frame, GstVideoFrame * out_frame);

static GstCapsFeatures *features_format_interlaced,
*features_format_interlaced_sysmem;

/* copies the given caps */
static GstCaps *
gst_video_convert_caps_remove_format_info (GstCaps * caps)
Expand All @@ -135,10 +138,14 @@ gst_video_convert_caps_remove_format_info (GstCaps * caps)
st = gst_structure_copy (st);
/* Only remove format info for the cases when we can actually convert */
if (!gst_caps_features_is_any (f)
&& gst_caps_features_is_equal (f,
GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))
&& (gst_caps_features_is_equal (f,
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",
NULL);
}

gst_caps_append_structure_full (res, st, gst_caps_features_copy (f));
}
Expand Down Expand Up @@ -743,6 +750,13 @@ plugin_init (GstPlugin * plugin)

_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",
GST_RANK_NONE, GST_TYPE_VIDEO_CONVERT);
}
Expand Down

0 comments on commit ca4240b

Please sign in to comment.