summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVineeth TM <vineeth.tm@samsung.com>2015-06-05 08:58:03 +0900
committerLuis de Bethencourt <luis.bg@samsung.com>2015-06-05 13:15:23 +0100
commit7824f4cf52dbc6221022edec2ed7402de72c993e (patch)
treec7663866031d33ca06d608a556d2fc8d98151dcb
parent15de547760839ff01ed9347c3c7b54a6c457e913 (diff)
simplevideomarkdetect: fix detect of videomark partially or fully outside video
In case of the videomark being partially or fully outside, an error was bein thrown saying, mark width is more than video width. And when the width, offset properties are set to maximum it resulted in crash. Instead of throwing error, added logic to detect the mark in case of partial visibility or dont show the mark when it is outside. https://bugzilla.gnome.org/show_bug.cgi?id=743908
-rw-r--r--gst/videosignal/gstsimplevideomarkdetect.c87
1 files changed, 73 insertions, 14 deletions
diff --git a/gst/videosignal/gstsimplevideomarkdetect.c b/gst/videosignal/gstsimplevideomarkdetect.c
index c04d90b82..d5f093f04 100644
--- a/gst/videosignal/gstsimplevideomarkdetect.c
+++ b/gst/videosignal/gstsimplevideomarkdetect.c
@@ -436,15 +436,27 @@ gst_video_detect_calc_brightness (GstSimpleVideoMarkDetect *
return sum / (255.0 * width * height);
}
+static gint
+calculate_pw (gint pw, gint x, gint width)
+{
+ if (x < 0)
+ pw += x;
+ else if ((x + pw) > width)
+ pw = width - x;
+
+ return pw;
+}
+
static void
gst_video_detect_yuv (GstSimpleVideoMarkDetect * simplevideomarkdetect,
GstVideoFrame * frame)
{
gdouble brightness;
gint i, pw, ph, row_stride, pixel_stride;
- gint width, height, req_width, req_height;
+ gint width, height, offset_calc, x, y;
guint8 *d;
guint64 pattern_data;
+ gint total_pattern;
width = frame->info.width;
height = frame->info.height;
@@ -454,22 +466,44 @@ gst_video_detect_yuv (GstSimpleVideoMarkDetect * simplevideomarkdetect,
row_stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
- req_width =
- (simplevideomarkdetect->pattern_count +
- simplevideomarkdetect->pattern_data_count) * pw +
- simplevideomarkdetect->left_offset;
- req_height = simplevideomarkdetect->bottom_offset + ph;
- if (req_width > width || req_height > height) {
- goto no_pattern;
- }
-
d = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
/* move to start of bottom left, adjust for offsets */
- d += row_stride * (height - ph - simplevideomarkdetect->bottom_offset) +
+ offset_calc =
+ row_stride * (height - ph - simplevideomarkdetect->bottom_offset) +
pixel_stride * simplevideomarkdetect->left_offset;
+ x = simplevideomarkdetect->left_offset;
+ y = height - ph - simplevideomarkdetect->bottom_offset;
+
+ total_pattern =
+ simplevideomarkdetect->pattern_count +
+ simplevideomarkdetect->pattern_data_count;
+ /* If x and y offset values are outside the video, no need to analyze */
+ if ((x + (pw * total_pattern)) < 0 || x > width || (y + height) < 0
+ || y > height) {
+ GST_ERROR_OBJECT (simplevideomarkdetect,
+ "simplevideomarkdetect pattern is outside the video. Not Analyzing.");
+ return;
+ }
+
+ /* Offset calculation less than 0, then reset to 0 */
+ if (offset_calc < 0)
+ offset_calc = 0;
+ /* Y position of mark is negative or pattern exceeds the video height,
+ then recalculate pattern height for partial display */
+ if (y < 0)
+ ph += y;
+ else if ((y + ph) > height)
+ ph = height - y;
+ /* If pattern height is less than 0, need not analyze anything */
+ if (ph < 0)
+ return;
+
+ /* move to start of bottom left */
+ d += offset_calc;
- /* analyse the bottom left pixels */
+ /* analyze the bottom left pixels */
for (i = 0; i < simplevideomarkdetect->pattern_count; i++) {
+ gint draw_pw;
/* calc brightness of width * height box */
brightness =
gst_video_detect_calc_brightness (simplevideomarkdetect, d, pw, ph,
@@ -493,8 +527,19 @@ gst_video_detect_yuv (GstSimpleVideoMarkDetect * simplevideomarkdetect,
goto no_pattern;
}
+ /* X position of mark is negative or pattern exceeds the video width,
+ then recalculate pattern width for partial display */
+ draw_pw = calculate_pw (pw, x, width);
+ /* If pattern width is less than 0, continue with the next pattern */
+ if (draw_pw < 0)
+ continue;
+
/* move to i-th pattern */
- d += pixel_stride * pw;
+ d += pixel_stride * draw_pw;
+ x += draw_pw;
+
+ if ((x + (pw * (total_pattern - i - 1))) < 0 || x >= width)
+ break;
}
GST_DEBUG_OBJECT (simplevideomarkdetect, "found pattern");
@@ -502,6 +547,7 @@ gst_video_detect_yuv (GstSimpleVideoMarkDetect * simplevideomarkdetect,
/* get the data of the pattern */
for (i = 0; i < simplevideomarkdetect->pattern_data_count; i++) {
+ gint draw_pw;
/* calc brightness of width * height box */
brightness =
gst_video_detect_calc_brightness (simplevideomarkdetect, d, pw, ph,
@@ -510,8 +556,21 @@ gst_video_detect_yuv (GstSimpleVideoMarkDetect * simplevideomarkdetect,
pattern_data <<= 1;
if (brightness > simplevideomarkdetect->pattern_center)
pattern_data |= 1;
+
+ /* X position of mark is negative or pattern exceeds the video width,
+ then recalculate pattern width for partial display */
+ draw_pw = calculate_pw (pw, x, width);
+ /* If pattern width is less than 0, continue with the next pattern */
+ if (draw_pw < 0)
+ continue;
+
/* move to i-th pattern data */
- d += pixel_stride * pw;
+ d += pixel_stride * draw_pw;
+ x += draw_pw;
+
+ if ((x + (pw * (simplevideomarkdetect->pattern_data_count - i - 1))) < 0
+ || x >= width)
+ break;
}
GST_DEBUG_OBJECT (simplevideomarkdetect, "have data %" G_GUINT64_FORMAT,