mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-03 01:02:19 +00:00
video-converter: handle mixed interlaced
When dealing with mixed interlaced, setup a scaler and chroma-resampler for both interlaced and progressive frames and switch between them depending on the interlace mode of the input frame.
This commit is contained in:
parent
0358e23baf
commit
b9bee1af8c
1 changed files with 69 additions and 45 deletions
|
@ -179,6 +179,8 @@ struct _GstVideoConverter
|
||||||
/* chroma upsample */
|
/* chroma upsample */
|
||||||
GstLineCache *upsample_lines;
|
GstLineCache *upsample_lines;
|
||||||
GstVideoChromaResample *upsample;
|
GstVideoChromaResample *upsample;
|
||||||
|
GstVideoChromaResample *upsample_p;
|
||||||
|
GstVideoChromaResample *upsample_i;
|
||||||
guint up_n_lines;
|
guint up_n_lines;
|
||||||
gint up_offset;
|
gint up_offset;
|
||||||
|
|
||||||
|
@ -194,6 +196,8 @@ struct _GstVideoConverter
|
||||||
gint h_scale_format;
|
gint h_scale_format;
|
||||||
GstLineCache *vscale_lines;
|
GstLineCache *vscale_lines;
|
||||||
GstVideoScaler *v_scaler;
|
GstVideoScaler *v_scaler;
|
||||||
|
GstVideoScaler *v_scaler_p;
|
||||||
|
GstVideoScaler *v_scaler_i;
|
||||||
gint v_scale_width;
|
gint v_scale_width;
|
||||||
gint v_scale_format;
|
gint v_scale_format;
|
||||||
|
|
||||||
|
@ -212,6 +216,8 @@ struct _GstVideoConverter
|
||||||
/* chroma downsample */
|
/* chroma downsample */
|
||||||
GstLineCache *downsample_lines;
|
GstLineCache *downsample_lines;
|
||||||
GstVideoChromaResample *downsample;
|
GstVideoChromaResample *downsample;
|
||||||
|
GstVideoChromaResample *downsample_p;
|
||||||
|
GstVideoChromaResample *downsample_i;
|
||||||
guint down_n_lines;
|
guint down_n_lines;
|
||||||
gint down_offset;
|
gint down_offset;
|
||||||
|
|
||||||
|
@ -1129,24 +1135,25 @@ chain_hscale (GstVideoConverter * convert, GstLineCache * prev)
|
||||||
static GstLineCache *
|
static GstLineCache *
|
||||||
chain_vscale (GstVideoConverter * convert, GstLineCache * prev)
|
chain_vscale (GstVideoConverter * convert, GstLineCache * prev)
|
||||||
{
|
{
|
||||||
GstVideoScalerFlags flags;
|
|
||||||
gint method;
|
gint method;
|
||||||
guint taps;
|
guint taps;
|
||||||
|
|
||||||
flags = GST_VIDEO_INFO_IS_INTERLACED (&convert->in_info) ?
|
|
||||||
GST_VIDEO_SCALER_FLAG_INTERLACED : 0;
|
|
||||||
|
|
||||||
method = GET_OPT_RESAMPLER_METHOD (convert);
|
method = GET_OPT_RESAMPLER_METHOD (convert);
|
||||||
taps = GET_OPT_RESAMPLER_TAPS (convert);
|
taps = GET_OPT_RESAMPLER_TAPS (convert);
|
||||||
|
|
||||||
convert->v_scaler =
|
if (GST_VIDEO_INFO_IS_INTERLACED (&convert->in_info)) {
|
||||||
gst_video_scaler_new (method, flags, taps, convert->in_height,
|
convert->v_scaler_i =
|
||||||
|
gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_INTERLACED,
|
||||||
|
taps, convert->in_height, convert->out_height, convert->config);
|
||||||
|
}
|
||||||
|
convert->v_scaler_p =
|
||||||
|
gst_video_scaler_new (method, 0, taps, convert->in_height,
|
||||||
convert->out_height, convert->config);
|
convert->out_height, convert->config);
|
||||||
convert->v_scale_width = convert->current_width;
|
convert->v_scale_width = convert->current_width;
|
||||||
convert->v_scale_format = convert->current_format;
|
convert->v_scale_format = convert->current_format;
|
||||||
convert->current_height = convert->out_height;
|
convert->current_height = convert->out_height;
|
||||||
|
|
||||||
gst_video_scaler_get_coeff (convert->v_scaler, 0, NULL, &taps);
|
gst_video_scaler_get_coeff (convert->v_scaler_p, 0, NULL, &taps);
|
||||||
|
|
||||||
GST_DEBUG ("chain vscale %d->%d, taps %d, method %d",
|
GST_DEBUG ("chain vscale %d->%d, taps %d, method %d",
|
||||||
convert->in_height, convert->out_height, taps, method);
|
convert->in_height, convert->out_height, taps, method);
|
||||||
|
@ -1596,12 +1603,18 @@ gst_video_converter_free (GstVideoConverter * convert)
|
||||||
|
|
||||||
g_return_if_fail (convert != NULL);
|
g_return_if_fail (convert != NULL);
|
||||||
|
|
||||||
if (convert->upsample)
|
if (convert->upsample_p)
|
||||||
gst_video_chroma_resample_free (convert->upsample);
|
gst_video_chroma_resample_free (convert->upsample_p);
|
||||||
if (convert->downsample)
|
if (convert->upsample_i)
|
||||||
gst_video_chroma_resample_free (convert->downsample);
|
gst_video_chroma_resample_free (convert->upsample_i);
|
||||||
if (convert->v_scaler)
|
if (convert->downsample_p)
|
||||||
gst_video_scaler_free (convert->v_scaler);
|
gst_video_chroma_resample_free (convert->downsample_p);
|
||||||
|
if (convert->downsample_i)
|
||||||
|
gst_video_chroma_resample_free (convert->downsample_i);
|
||||||
|
if (convert->v_scaler_p)
|
||||||
|
gst_video_scaler_free (convert->v_scaler_p);
|
||||||
|
if (convert->v_scaler_i)
|
||||||
|
gst_video_scaler_free (convert->v_scaler_i);
|
||||||
if (convert->h_scaler)
|
if (convert->h_scaler)
|
||||||
gst_video_scaler_free (convert->h_scaler);
|
gst_video_scaler_free (convert->h_scaler);
|
||||||
|
|
||||||
|
@ -1813,46 +1826,31 @@ video_converter_compute_resample (GstVideoConverter * convert)
|
||||||
sfinfo = in_info->finfo;
|
sfinfo = in_info->finfo;
|
||||||
dfinfo = out_info->finfo;
|
dfinfo = out_info->finfo;
|
||||||
|
|
||||||
|
GST_DEBUG ("site: %d->%d, w_sub: %d->%d, h_sub: %d->%d", in_info->chroma_site,
|
||||||
|
out_info->chroma_site, sfinfo->w_sub[2], dfinfo->w_sub[2],
|
||||||
|
sfinfo->h_sub[2], dfinfo->h_sub[2]);
|
||||||
|
|
||||||
if (sfinfo->w_sub[2] != dfinfo->w_sub[2] ||
|
if (sfinfo->w_sub[2] != dfinfo->w_sub[2] ||
|
||||||
sfinfo->h_sub[2] != dfinfo->h_sub[2] ||
|
sfinfo->h_sub[2] != dfinfo->h_sub[2] ||
|
||||||
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) {
|
||||||
GstVideoChromaFlags flags = (GST_VIDEO_INFO_IS_INTERLACED (in_info) ?
|
if (GST_VIDEO_INFO_IS_INTERLACED (in_info)) {
|
||||||
GST_VIDEO_CHROMA_FLAG_INTERLACED : 0);
|
convert->upsample_i = gst_video_chroma_resample_new (0,
|
||||||
|
in_info->chroma_site, GST_VIDEO_CHROMA_FLAG_INTERLACED,
|
||||||
convert->upsample = gst_video_chroma_resample_new (0,
|
sfinfo->unpack_format, sfinfo->w_sub[2], sfinfo->h_sub[2]);
|
||||||
in_info->chroma_site, flags, sfinfo->unpack_format, sfinfo->w_sub[2],
|
convert->downsample_i =
|
||||||
|
gst_video_chroma_resample_new (0, out_info->chroma_site,
|
||||||
|
GST_VIDEO_CHROMA_FLAG_INTERLACED, dfinfo->unpack_format,
|
||||||
|
-dfinfo->w_sub[2], -dfinfo->h_sub[2]);
|
||||||
|
}
|
||||||
|
convert->upsample_p = gst_video_chroma_resample_new (0,
|
||||||
|
in_info->chroma_site, 0, sfinfo->unpack_format, sfinfo->w_sub[2],
|
||||||
sfinfo->h_sub[2]);
|
sfinfo->h_sub[2]);
|
||||||
|
convert->downsample_p = gst_video_chroma_resample_new (0,
|
||||||
convert->downsample = gst_video_chroma_resample_new (0,
|
out_info->chroma_site, 0, dfinfo->unpack_format, -dfinfo->w_sub[2],
|
||||||
out_info->chroma_site, flags, dfinfo->unpack_format, -dfinfo->w_sub[2],
|
|
||||||
-dfinfo->h_sub[2]);
|
-dfinfo->h_sub[2]);
|
||||||
|
|
||||||
} else {
|
|
||||||
convert->upsample = NULL;
|
|
||||||
convert->downsample = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convert->upsample) {
|
|
||||||
gst_video_chroma_resample_get_info (convert->upsample,
|
|
||||||
&convert->up_n_lines, &convert->up_offset);
|
|
||||||
} else {
|
|
||||||
convert->up_n_lines = 1;
|
|
||||||
convert->up_offset = 0;
|
|
||||||
}
|
|
||||||
if (convert->downsample) {
|
|
||||||
gst_video_chroma_resample_get_info (convert->downsample,
|
|
||||||
&convert->down_n_lines, &convert->down_offset);
|
|
||||||
} else {
|
|
||||||
convert->down_n_lines = 1;
|
|
||||||
convert->down_offset = 0;
|
|
||||||
}
|
|
||||||
GST_DEBUG ("upsample: %p, site: %d, offset %d, n_lines %d", convert->upsample,
|
|
||||||
in_info->chroma_site, convert->up_offset, convert->up_n_lines);
|
|
||||||
GST_DEBUG ("downsample: %p, site: %d, offset %d, n_lines %d",
|
|
||||||
convert->downsample, out_info->chroma_site, convert->down_offset,
|
|
||||||
convert->down_n_lines);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FRAME_GET_PLANE_STRIDE(frame, plane) \
|
#define FRAME_GET_PLANE_STRIDE(frame, plane) \
|
||||||
|
@ -2173,6 +2171,32 @@ video_converter_generic (GstVideoConverter * convert, const GstVideoFrame * src,
|
||||||
convert->src = src;
|
convert->src = src;
|
||||||
convert->dest = dest;
|
convert->dest = dest;
|
||||||
|
|
||||||
|
if (GST_VIDEO_FRAME_IS_INTERLACED (src)) {
|
||||||
|
GST_DEBUG ("setup interlaced frame");
|
||||||
|
convert->upsample = convert->upsample_i;
|
||||||
|
convert->downsample = convert->downsample_i;
|
||||||
|
convert->v_scaler = convert->v_scaler_i;
|
||||||
|
} else {
|
||||||
|
GST_DEBUG ("setup progressive frame");
|
||||||
|
convert->upsample = convert->upsample_p;
|
||||||
|
convert->downsample = convert->downsample_p;
|
||||||
|
convert->v_scaler = convert->v_scaler_p;
|
||||||
|
}
|
||||||
|
if (convert->upsample) {
|
||||||
|
gst_video_chroma_resample_get_info (convert->upsample,
|
||||||
|
&convert->up_n_lines, &convert->up_offset);
|
||||||
|
} else {
|
||||||
|
convert->up_n_lines = 1;
|
||||||
|
convert->up_offset = 0;
|
||||||
|
}
|
||||||
|
if (convert->downsample) {
|
||||||
|
gst_video_chroma_resample_get_info (convert->downsample,
|
||||||
|
&convert->down_n_lines, &convert->down_offset);
|
||||||
|
} else {
|
||||||
|
convert->down_n_lines = 1;
|
||||||
|
convert->down_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
pack_lines = convert->pack_nlines; /* only 1 for now */
|
pack_lines = convert->pack_nlines; /* only 1 for now */
|
||||||
pstride = convert->pack_pstride;
|
pstride = convert->pack_pstride;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue