Esempio n. 1
0
static void
gst_video_balance_planar411_ip (GstVideoBalance * videobalance, guint8 * data,
    gint width, gint height)
{
  int x, y;
  guint8 *ydata;
  guint8 *udata, *vdata;
  gint ystride, ustride, vstride;
  gint width2, height2;

  ydata = data + GST_VIDEO_I420_Y_OFFSET (width, height);
  ystride = GST_VIDEO_I420_Y_ROWSTRIDE (width);

  for (y = 0; y < height; y++) {
    oil_tablelookup_u8 (ydata, 1, ydata, 1, videobalance->tabley, 1, width);
    ydata += ystride;
  }

  width2 = width >> 1;
  height2 = height >> 1;

  udata = data + GST_VIDEO_I420_U_OFFSET (width, height);
  vdata = data + GST_VIDEO_I420_V_OFFSET (width, height);
  ustride = GST_VIDEO_I420_U_ROWSTRIDE (width);
  vstride = GST_VIDEO_I420_V_ROWSTRIDE (width);

  for (y = 0; y < height2; y++) {
    guint8 *uptr, *vptr;
    guint8 u1, v1;

    uptr = udata + y * ustride;
    vptr = vdata + y * vstride;

    for (x = 0; x < width2; x++) {
      u1 = *uptr;
      v1 = *vptr;

      *uptr++ = videobalance->tableu[u1][v1];
      *vptr++ = videobalance->tablev[u1][v1];
    }
  }
}
Esempio n. 2
0
static GstFlowReturn
gst_video_flip_flip (GstVideoFlip * videoflip, guint8 * dest,
    guint8 * src, int sw, int sh, int dw, int dh)
{
  GstFlowReturn ret = GST_FLOW_OK;
  int x, y;
  guint8 *s = src, *d = dest;

  switch (videoflip->method) {
    case GST_VIDEO_FLIP_METHOD_90R:
      /* Flip Y */
      for (y = 0; y < dh; y++) {
        for (x = 0; x < dw; x++) {
          d[y * GST_VIDEO_I420_Y_ROWSTRIDE (dw) + x] =
              s[(sh - 1 - x) * GST_VIDEO_I420_Y_ROWSTRIDE (sw) + y];
        }
      }
      /* Flip U */
      s = src + GST_VIDEO_I420_U_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_U_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_U_ROWSTRIDE (dw) + x] =
              s[(sh / 2 - 1 - x) * GST_VIDEO_I420_U_ROWSTRIDE (sw) + y];
        }
      }
      /* Flip V */
      s = src + GST_VIDEO_I420_V_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_V_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_V_ROWSTRIDE (dw) + x] =
              s[(sh / 2 - 1 - x) * GST_VIDEO_I420_V_ROWSTRIDE (sw) + y];
        }
      }
      break;
    case GST_VIDEO_FLIP_METHOD_90L:
      /* Flip Y */
      for (y = 0; y < dh; y++) {
        for (x = 0; x < dw; x++) {
          d[y * GST_VIDEO_I420_Y_ROWSTRIDE (dw) + x] =
              s[x * GST_VIDEO_I420_Y_ROWSTRIDE (sw) + (sw - 1 - y)];
        }
      }
      /* Flip U */
      s = src + GST_VIDEO_I420_U_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_U_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_U_ROWSTRIDE (dw) + x] =
              s[x * GST_VIDEO_I420_U_ROWSTRIDE (sw) + (sw / 2 - 1 - y)];
        }
      }
      /* Flip V */
      s = src + GST_VIDEO_I420_V_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_V_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_V_ROWSTRIDE (dw) + x] =
              s[x * GST_VIDEO_I420_V_ROWSTRIDE (sw) + (sw / 2 - 1 - y)];
        }
      }
      break;
    case GST_VIDEO_FLIP_METHOD_180:
      /* Flip Y */
      for (y = 0; y < dh; y++) {
        for (x = 0; x < dw; x++) {
          d[y * GST_VIDEO_I420_Y_ROWSTRIDE (dw) + x] =
              s[(sh - 1 - y) * GST_VIDEO_I420_Y_ROWSTRIDE (sw) + (sw - 1 - x)];
        }
      }
      /* Flip U */
      s = src + GST_VIDEO_I420_U_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_U_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_U_ROWSTRIDE (dw) + x] =
              s[(sh / 2 - 1 - y) * GST_VIDEO_I420_U_ROWSTRIDE (sw) + (sw / 2 -
                  1 - x)];
        }
      }
      /* Flip V */
      s = src + GST_VIDEO_I420_V_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_V_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_V_ROWSTRIDE (dw) + x] =
              s[(sh / 2 - 1 - y) * GST_VIDEO_I420_V_ROWSTRIDE (sw) + (sw / 2 -
                  1 - x)];
        }
      }
      break;
    case GST_VIDEO_FLIP_METHOD_HORIZ:
      /* Flip Y */
      for (y = 0; y < dh; y++) {
        for (x = 0; x < dw; x++) {
          d[y * GST_VIDEO_I420_Y_ROWSTRIDE (dw) + x] =
              s[y * GST_VIDEO_I420_Y_ROWSTRIDE (sw) + (sw - 1 - x)];
        }
      }
      /* Flip U */
      s = src + GST_VIDEO_I420_U_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_U_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_U_ROWSTRIDE (dw) + x] =
              s[y * GST_VIDEO_I420_U_ROWSTRIDE (sw) + (sw / 2 - 1 - x)];
        }
      }
      /* Flip V */
      s = src + GST_VIDEO_I420_V_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_V_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_V_ROWSTRIDE (dw) + x] =
              s[y * GST_VIDEO_I420_V_ROWSTRIDE (sw) + (sw / 2 - 1 - x)];
        }
      }
      break;
    case GST_VIDEO_FLIP_METHOD_VERT:
      /* Flip Y */
      for (y = 0; y < dh; y++) {
        for (x = 0; x < dw; x++) {
          d[y * GST_VIDEO_I420_Y_ROWSTRIDE (dw) + x] =
              s[(sh - 1 - y) * GST_VIDEO_I420_Y_ROWSTRIDE (sw) + x];
        }
      }
      /* Flip U */
      s = src + GST_VIDEO_I420_U_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_U_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_U_ROWSTRIDE (dw) + x] =
              s[(sh / 2 - 1 - y) * GST_VIDEO_I420_U_ROWSTRIDE (sw) + x];
        }
      }
      /* Flip V */
      s = src + GST_VIDEO_I420_V_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_V_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_V_ROWSTRIDE (dw) + x] =
              s[(sh / 2 - 1 - y) * GST_VIDEO_I420_V_ROWSTRIDE (sw) + x];
        }
      }
      break;
    case GST_VIDEO_FLIP_METHOD_TRANS:
      /* Flip Y */
      for (y = 0; y < dh; y++) {
        for (x = 0; x < dw; x++) {
          d[y * GST_VIDEO_I420_Y_ROWSTRIDE (dw) + x] =
              s[x * GST_VIDEO_I420_Y_ROWSTRIDE (sw) + y];
        }
      }
      /* Flip U */
      s = src + GST_VIDEO_I420_U_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_U_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_U_ROWSTRIDE (dw) + x] =
              s[x * GST_VIDEO_I420_U_ROWSTRIDE (sw) + y];
        }
      }
      /* Flip V */
      s = src + GST_VIDEO_I420_V_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_V_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_V_ROWSTRIDE (dw) + x] =
              s[x * GST_VIDEO_I420_V_ROWSTRIDE (sw) + y];
        }
      }
      break;
    case GST_VIDEO_FLIP_METHOD_OTHER:
      /* Flip Y */
      for (y = 0; y < dh; y++) {
        for (x = 0; x < dw; x++) {
          d[y * GST_VIDEO_I420_Y_ROWSTRIDE (dw) + x] =
              s[(sh - 1 - x) * GST_VIDEO_I420_Y_ROWSTRIDE (sw) + (sw - 1 - y)];
        }
      }
      /* Flip U */
      s = src + GST_VIDEO_I420_U_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_U_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_U_ROWSTRIDE (dw) + x] =
              s[(sh / 2 - 1 - x) * GST_VIDEO_I420_U_ROWSTRIDE (sw) + (sw / 2 -
                  1 - y)];
        }
      }
      /* Flip V */
      s = src + GST_VIDEO_I420_V_OFFSET (sw, sh);
      d = dest + GST_VIDEO_I420_V_OFFSET (dw, dh);
      for (y = 0; y < dh / 2; y++) {
        for (x = 0; x < dw / 2; x++) {
          d[y * GST_VIDEO_I420_V_ROWSTRIDE (dw) + x] =
              s[(sh / 2 - 1 - x) * GST_VIDEO_I420_V_ROWSTRIDE (sw) + (sw / 2 -
                  1 - y)];
        }
      }
      break;
    case GST_VIDEO_FLIP_METHOD_IDENTITY:
      memcpy (d, s, GST_VIDEO_I420_SIZE (dw, dh));
      break;
    default:
      ret = GST_FLOW_ERROR;
      break;
  }

  return ret;
}
Esempio n. 3
0
static GstFlowReturn
gst_cairo_time_overlay_transform (GstBaseTransform * trans, GstBuffer * in,
    GstBuffer * out)
{
  GstCairoTimeOverlay *timeoverlay;
  int width;
  int height;
  int b_width;
  int stride_y, stride_u, stride_v;
  char *string;
  int i, j;
  unsigned char *image;
  cairo_text_extents_t extents;
  guint8 *dest, *src;
  cairo_surface_t *font_surface;
  cairo_t *text_cairo;
  GstFlowReturn ret = GST_FLOW_OK;

  timeoverlay = GST_CAIRO_TIME_OVERLAY (trans);

  gst_buffer_copy_metadata (out, in, GST_BUFFER_COPY_TIMESTAMPS);

  src = GST_BUFFER_DATA (in);
  dest = GST_BUFFER_DATA (out);

  width = timeoverlay->width;
  height = timeoverlay->height;

  /* create surface for font rendering */
  /* FIXME: preparation of the surface could also be done once when settings
   * change */
  image = g_malloc (4 * width * timeoverlay->text_height);

  font_surface =
      cairo_image_surface_create_for_data (image, CAIRO_FORMAT_ARGB32, width,
      timeoverlay->text_height, width * 4);
  text_cairo = cairo_create (font_surface);
  cairo_surface_destroy (font_surface);
  font_surface = NULL;

  /* we draw a rectangle because the compositing on the buffer below
   * doesn't do alpha */
  cairo_save (text_cairo);
  cairo_rectangle (text_cairo, 0, 0, width, timeoverlay->text_height);
  cairo_set_source_rgba (text_cairo, 0, 0, 0, 1);
  cairo_set_operator (text_cairo, CAIRO_OPERATOR_SOURCE);
  cairo_fill (text_cairo);
  cairo_restore (text_cairo);

  string = gst_cairo_time_overlay_print_smpte_time (GST_BUFFER_TIMESTAMP (in));
  cairo_save (text_cairo);
  cairo_select_font_face (text_cairo, "monospace", 0, 0);
  cairo_set_font_size (text_cairo, 20);
  cairo_text_extents (text_cairo, string, &extents);
  cairo_set_source_rgb (text_cairo, 1, 1, 1);
  cairo_move_to (text_cairo, 0, timeoverlay->text_height - 2);
  cairo_show_text (text_cairo, string);
  g_free (string);

  cairo_restore (text_cairo);

  /* blend width; should retain a max text width so it doesn't jitter */
  b_width = extents.width;
  if (b_width > width)
    b_width = width;

  stride_y = GST_VIDEO_I420_Y_ROWSTRIDE (width);
  stride_u = GST_VIDEO_I420_U_ROWSTRIDE (width);
  stride_v = GST_VIDEO_I420_V_ROWSTRIDE (width);

  memcpy (dest, src, GST_BUFFER_SIZE (in));
  for (i = 0; i < timeoverlay->text_height; i++) {
    for (j = 0; j < b_width; j++) {
      ((unsigned char *) dest)[i * stride_y + j] =
          image[(i * width + j) * 4 + 0];
    }
  }
  for (i = 0; i < timeoverlay->text_height / 2; i++) {
    memset (dest + GST_VIDEO_I420_U_OFFSET (width, height) + i * stride_u, 128,
        b_width / 2);
    memset (dest + GST_VIDEO_I420_V_OFFSET (width, height) + i * stride_v, 128,
        b_width / 2);
  }

  cairo_destroy (text_cairo);
  text_cairo = NULL;
  g_free (image);

  return ret;
}