static void gst_video_detect_yuv (GstVideoDetect * videodetect, GstBuffer * buffer) { GstVideoFormat format; gdouble brightness; gint i, pw, ph, row_stride, pixel_stride, offset; gint width, height, req_width, req_height; guint8 *d, *data; guint64 pattern_data; data = GST_BUFFER_DATA (buffer); format = videodetect->format; width = videodetect->width; height = videodetect->height; pw = videodetect->pattern_width; ph = videodetect->pattern_height; row_stride = gst_video_format_get_row_stride (format, 0, width); pixel_stride = gst_video_format_get_pixel_stride (format, 0); offset = gst_video_format_get_component_offset (format, 0, width, height); req_width = (videodetect->pattern_count + videodetect->pattern_data_count) * pw + videodetect->left_offset; req_height = videodetect->bottom_offset + ph; if (req_width > width || req_height > height) { goto no_pattern; } /* analyse the bottom left pixels */ for (i = 0; i < videodetect->pattern_count; i++) { d = data + offset; /* move to start of bottom left, adjust for offsets */ d += row_stride * (height - ph - videodetect->bottom_offset) + pixel_stride * videodetect->left_offset; /* move to i-th pattern */ d += pixel_stride * pw * i; /* calc brightness of width * height box */ brightness = gst_video_detect_calc_brightness (videodetect, d, pw, ph, row_stride, pixel_stride); GST_DEBUG_OBJECT (videodetect, "brightness %f", brightness); if (i & 1) { /* odd pixels must be white, all pixels darker than the center + * sensitivity are considered wrong. */ if (brightness < (videodetect->pattern_center + videodetect->pattern_sensitivity)) goto no_pattern; } else { /* even pixels must be black, pixels lighter than the center - sensitivity * are considered wrong. */ if (brightness > (videodetect->pattern_center - videodetect->pattern_sensitivity)) goto no_pattern; } } GST_DEBUG_OBJECT (videodetect, "found pattern"); pattern_data = 0; /* get the data of the pattern */ for (i = 0; i < videodetect->pattern_data_count; i++) { d = data + offset; /* move to start of bottom left, adjust for offsets */ d += row_stride * (height - ph - videodetect->bottom_offset) + pixel_stride * videodetect->left_offset; /* move after the fixed pattern */ d += pixel_stride * (videodetect->pattern_count * pw); /* move to i-th pattern data */ d += pixel_stride * pw * i; /* calc brightness of width * height box */ brightness = gst_video_detect_calc_brightness (videodetect, d, pw, ph, row_stride, pixel_stride); /* update pattern, we just use the center to decide between black and white. */ pattern_data <<= 1; if (brightness > videodetect->pattern_center) pattern_data |= 1; } GST_DEBUG_OBJECT (videodetect, "have data %" G_GUINT64_FORMAT, pattern_data); videodetect->in_pattern = TRUE; gst_video_detect_post_message (videodetect, buffer, pattern_data); return; no_pattern: { GST_DEBUG_OBJECT (videodetect, "no pattern found"); if (videodetect->in_pattern) { videodetect->in_pattern = FALSE; gst_video_detect_post_message (videodetect, buffer, 0); } return; } }
static void gst_video_detect_yuv (GstSimpleVideoMarkDetect * simplevideomarkdetect, GstVideoFrame * frame) { gdouble brightness; gint i, pw, ph, row_stride, pixel_stride; gint width, height, offset_calc, x, y; guint8 *d; guint64 pattern_data; gint total_pattern; width = frame->info.width; height = frame->info.height; pw = simplevideomarkdetect->pattern_width; ph = simplevideomarkdetect->pattern_height; row_stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0); d = GST_VIDEO_FRAME_COMP_DATA (frame, 0); /* move to start of bottom left, adjust for offsets */ 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; /* 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, row_stride, pixel_stride); GST_DEBUG_OBJECT (simplevideomarkdetect, "brightness %f", brightness); if (i & 1) { /* odd pixels must be white, all pixels darker than the center + * sensitivity are considered wrong. */ if (brightness < (simplevideomarkdetect->pattern_center + simplevideomarkdetect->pattern_sensitivity)) goto no_pattern; } else { /* even pixels must be black, pixels lighter than the center - sensitivity * are considered wrong. */ if (brightness > (simplevideomarkdetect->pattern_center - simplevideomarkdetect->pattern_sensitivity)) 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 * draw_pw; x += draw_pw; if ((x + (pw * (total_pattern - i - 1))) < 0 || x >= width) break; } GST_DEBUG_OBJECT (simplevideomarkdetect, "found pattern"); pattern_data = 0; /* 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, row_stride, pixel_stride); /* update pattern, we just use the center to decide between black and white. */ 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 * 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, pattern_data); simplevideomarkdetect->in_pattern = TRUE; gst_video_detect_post_message (simplevideomarkdetect, frame->buffer, pattern_data); return; no_pattern: { GST_DEBUG_OBJECT (simplevideomarkdetect, "no pattern found"); if (simplevideomarkdetect->in_pattern) { simplevideomarkdetect->in_pattern = FALSE; gst_video_detect_post_message (simplevideomarkdetect, frame->buffer, 0); } return; } }