コード例 #1
0
ファイル: gstvideodetect.c プロジェクト: spunktsch/svtplayer
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;
  }
}
コード例 #2
0
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;
  }
}