mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +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);
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue