From 24989b53fc5ec1f4d95eecdde507e455b19d0a14 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 19 Nov 2014 12:05:02 +0100 Subject: [PATCH] video-info: handle interlaced size correctly Refactor GstVideoInfo init, make function to set default colorimetry. Call fill_planes after we configure the GstVideoInfo with parameters from the caps. The size of the chroma planes for interlaced vertically subsampled formats needs to be rounded up to 2, we have 2 fields with each the same anount of chroma lines. --- gst-libs/gst/video/video-converter.c | 2 +- gst-libs/gst/video/video-info.c | 100 ++++++++++++++++----------- 2 files changed, 61 insertions(+), 41 deletions(-) diff --git a/gst-libs/gst/video/video-converter.c b/gst-libs/gst/video/video-converter.c index feab73a1da..98b1599a5d 100644 --- a/gst-libs/gst/video/video-converter.c +++ b/gst-libs/gst/video/video-converter.c @@ -1099,7 +1099,7 @@ chain_vscale (GstVideoConverter * convert, GstLineCache * prev) gst_video_scaler_get_coeff (convert->v_scaler, 0, NULL, &taps); GST_DEBUG ("chain vscale %d->%d, taps %d, method %d", - convert->in_width, convert->out_height, taps, method); + convert->in_height, convert->out_height, taps, method); prev = convert->vscale_lines = gst_line_cache_new (prev); prev->pass_alloc = (taps == 1); diff --git a/gst-libs/gst/video/video-info.c b/gst-libs/gst/video/video-info.c index b048e6e7b4..ccdf4a4fb2 100644 --- a/gst-libs/gst/video/video-info.c +++ b/gst-libs/gst/video/video-info.c @@ -72,6 +72,28 @@ static const GstVideoColorimetry default_color[] = { MAKE_COLORIMETRY (_UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN), }; +static void +set_default_colorimetry (GstVideoInfo * info) +{ + const GstVideoFormatInfo *finfo = info->finfo; + + if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) { + if (info->height > 576) { + info->chroma_site = GST_VIDEO_CHROMA_SITE_H_COSITED; + info->colorimetry = default_color[DEFAULT_YUV_HD]; + } else { + info->chroma_site = GST_VIDEO_CHROMA_SITE_NONE; + info->colorimetry = default_color[DEFAULT_YUV_SD]; + } + } else if (GST_VIDEO_FORMAT_INFO_IS_GRAY (finfo)) { + info->colorimetry = default_color[DEFAULT_GRAY]; + } else if (GST_VIDEO_FORMAT_INFO_IS_RGB (finfo)) { + info->colorimetry = default_color[DEFAULT_RGB]; + } else { + info->colorimetry = default_color[DEFAULT_UNKNOWN]; + } +} + /** * gst_video_info_set_format: * @info: a #GstVideoInfo @@ -87,35 +109,16 @@ void gst_video_info_set_format (GstVideoInfo * info, GstVideoFormat format, guint width, guint height) { - const GstVideoFormatInfo *finfo; - g_return_if_fail (info != NULL); g_return_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN); gst_video_info_init (info); - finfo = gst_video_format_get_info (format); - - info->flags = 0; - info->finfo = finfo; + info->finfo = gst_video_format_get_info (format); info->width = width; info->height = height; - if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) { - if (height > 576) { - info->chroma_site = GST_VIDEO_CHROMA_SITE_H_COSITED; - info->colorimetry = default_color[DEFAULT_YUV_HD]; - } else { - info->chroma_site = GST_VIDEO_CHROMA_SITE_NONE; - info->colorimetry = default_color[DEFAULT_YUV_SD]; - } - } else if (GST_VIDEO_FORMAT_INFO_IS_GRAY (finfo)) { - info->colorimetry = default_color[DEFAULT_GRAY]; - } else if (GST_VIDEO_FORMAT_INFO_IS_RGB (finfo)) { - info->colorimetry = default_color[DEFAULT_RGB]; - } else { - info->colorimetry = default_color[DEFAULT_UNKNOWN]; - } + set_default_colorimetry (info); fill_planes (info); } @@ -197,7 +200,11 @@ gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps) format != GST_VIDEO_FORMAT_ENCODED) goto no_height; - gst_video_info_set_format (info, format, width, height); + gst_video_info_init (info); + + info->finfo = gst_video_format_get_info (format); + info->width = width; + info->height = height; if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) { if (fps_n == 0) { @@ -231,6 +238,8 @@ gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps) if ((s = gst_structure_get_string (structure, "colorimetry"))) gst_video_colorimetry_from_string (&info->colorimetry, s); + else + set_default_colorimetry (info); if (gst_structure_get_fraction (structure, "pixel-aspect-ratio", &par_n, &par_d)) { @@ -240,6 +249,8 @@ gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps) info->par_n = 1; info->par_d = 1; } + fill_planes (info); + return TRUE; /* ERROR */ @@ -376,7 +387,7 @@ gst_video_info_to_caps (GstVideoInfo * info) static int fill_planes (GstVideoInfo * info) { - gsize width, height; + gsize width, height, cr_h; width = (gsize) info->width; height = (gsize) info->height; @@ -470,10 +481,13 @@ fill_planes (GstVideoInfo * info) info->stride[2] = info->stride[1]; info->offset[0] = 0; info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); - info->offset[2] = info->offset[1] + - info->stride[1] * (GST_ROUND_UP_2 (height) / 2); - info->size = info->offset[2] + - info->stride[2] * (GST_ROUND_UP_2 (height) / 2); + cr_h = GST_ROUND_UP_2 (height) / 2; + if (GST_VIDEO_INFO_IS_INTERLACED (info)) + cr_h = GST_ROUND_UP_2 (cr_h); + info->offset[2] = info->offset[1] + info->stride[1] * cr_h; + info->size = info->offset[2] + info->stride[2] * cr_h; + GST_DEBUG ("%d %d %d", GST_VIDEO_INFO_IS_INTERLACED (info), + (int) info->offset[2], (int) info->size); break; case GST_VIDEO_FORMAT_Y41B: info->stride[0] = GST_ROUND_UP_4 (width); @@ -511,7 +525,10 @@ fill_planes (GstVideoInfo * info) info->stride[1] = info->stride[0]; info->offset[0] = 0; info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); - info->size = info->stride[0] * GST_ROUND_UP_2 (height) * 3 / 2; + cr_h = GST_ROUND_UP_2 (height) / 2; + if (GST_VIDEO_INFO_IS_INTERLACED (info)) + cr_h = GST_ROUND_UP_2 (cr_h); + info->size = info->offset[1] + info->stride[0] * cr_h; break; case GST_VIDEO_FORMAT_NV16: info->stride[0] = GST_ROUND_UP_4 (width); @@ -534,10 +551,11 @@ fill_planes (GstVideoInfo * info) info->stride[3] = info->stride[0]; info->offset[0] = 0; info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); - info->offset[2] = info->offset[1] + - info->stride[1] * (GST_ROUND_UP_2 (height) / 2); - info->offset[3] = info->offset[2] + - info->stride[2] * (GST_ROUND_UP_2 (height) / 2); + cr_h = GST_ROUND_UP_2 (height) / 2; + if (GST_VIDEO_INFO_IS_INTERLACED (info)) + cr_h = GST_ROUND_UP_2 (cr_h); + info->offset[2] = info->offset[1] + info->stride[1] * cr_h; + info->offset[3] = info->offset[2] + info->stride[2] * cr_h; info->size = info->offset[3] + info->stride[0] * GST_ROUND_UP_2 (height); break; case GST_VIDEO_FORMAT_YUV9: @@ -547,10 +565,11 @@ fill_planes (GstVideoInfo * info) info->stride[2] = info->stride[1]; info->offset[0] = 0; info->offset[1] = info->stride[0] * height; - info->offset[2] = info->offset[1] + - info->stride[1] * (GST_ROUND_UP_4 (height) / 4); - info->size = info->offset[2] + - info->stride[2] * (GST_ROUND_UP_4 (height) / 4); + cr_h = GST_ROUND_UP_4 (height) / 4; + if (GST_VIDEO_INFO_IS_INTERLACED (info)) + cr_h = GST_ROUND_UP_2 (cr_h); + info->offset[2] = info->offset[1] + info->stride[1] * cr_h; + info->size = info->offset[2] + info->stride[2] * cr_h; break; case GST_VIDEO_FORMAT_I420_10LE: case GST_VIDEO_FORMAT_I420_10BE: @@ -559,10 +578,11 @@ fill_planes (GstVideoInfo * info) info->stride[2] = info->stride[1]; info->offset[0] = 0; info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); - info->offset[2] = info->offset[1] + - info->stride[1] * (GST_ROUND_UP_2 (height) / 2); - info->size = info->offset[2] + - info->stride[2] * (GST_ROUND_UP_2 (height) / 2); + cr_h = GST_ROUND_UP_2 (height) / 2; + if (GST_VIDEO_INFO_IS_INTERLACED (info)) + cr_h = GST_ROUND_UP_2 (cr_h); + info->offset[2] = info->offset[1] + info->stride[1] * cr_h; + info->size = info->offset[2] + info->stride[2] * cr_h; break; case GST_VIDEO_FORMAT_I422_10LE: case GST_VIDEO_FORMAT_I422_10BE: