static GstFlowReturn
gst_pixbufscale_transform_frame (GstVideoFilter * filter,
    GstVideoFrame * in, GstVideoFrame * out)
{
  GstPixbufScale *scale;
  GdkPixbuf *src_pixbuf, *dest_pixbuf;

  scale = GST_PIXBUFSCALE (filter);

  src_pixbuf =
      gdk_pixbuf_new_from_data (GST_VIDEO_FRAME_COMP_DATA (in, 0),
      GDK_COLORSPACE_RGB, FALSE, 8, GST_VIDEO_FRAME_WIDTH (in),
      GST_VIDEO_FRAME_HEIGHT (in),
      GST_VIDEO_FRAME_COMP_STRIDE (in, 0), NULL, NULL);

  dest_pixbuf =
      gdk_pixbuf_new_from_data (GST_VIDEO_FRAME_COMP_DATA (out, 0),
      GDK_COLORSPACE_RGB, FALSE, 8, GST_VIDEO_FRAME_WIDTH (out),
      GST_VIDEO_FRAME_HEIGHT (out),
      GST_VIDEO_FRAME_COMP_STRIDE (out, 0), NULL, NULL);

  gdk_pixbuf_scale (src_pixbuf, dest_pixbuf, 0, 0,
      GST_VIDEO_FRAME_WIDTH (out),
      GST_VIDEO_FRAME_HEIGHT (out), 0, 0,
      (double) GST_VIDEO_FRAME_WIDTH (out) / GST_VIDEO_FRAME_WIDTH (in),
      (double) GST_VIDEO_FRAME_HEIGHT (out) / GST_VIDEO_FRAME_HEIGHT (in),
      scale->gdk_method);

  g_object_unref (src_pixbuf);
  g_object_unref (dest_pixbuf);

  return GST_FLOW_OK;
}
static void
fill_image_packed8_3 (opj_image_t * image, GstVideoFrame * frame)
{
  gint x, y, w, h;
  const guint8 *data_in, *tmp;
  gint *data_out[3];
  gint sstride;

  w = GST_VIDEO_FRAME_WIDTH (frame);
  h = GST_VIDEO_FRAME_HEIGHT (frame);
  data_in = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
  sstride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);

  data_out[0] = image->comps[0].data;
  data_out[1] = image->comps[1].data;
  data_out[2] = image->comps[2].data;

  for (y = 0; y < h; y++) {
    tmp = data_in;

    for (x = 0; x < w; x++) {
      *data_out[0] = tmp[1];
      *data_out[1] = tmp[2];
      *data_out[2] = tmp[3];

      tmp += 4;
      data_out[0]++;
      data_out[1]++;
      data_out[2]++;
    }
    data_in += sstride;
  }
}
Exemple #3
0
/* this function does the actual processing
 */
static GstFlowReturn
gst_yuv_to_rgb_transform_frame (GstVideoFilter *filter, GstVideoFrame *in_frame, GstVideoFrame *out_frame)
{
  GstYuvToRgb *rgbtoyuv = GST_YUVTORGB_CAST (filter);
  gint width, height, stride;
  gint y_stride, uv_stride;
  guint32 *out_data;
  guint8 *y_in, *u_in, *v_in;

  y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0);
  uv_stride = GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1);

  y_in = (guint8*) GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
  u_in = (guint8*) GST_VIDEO_FRAME_PLANE_DATA (in_frame, 1);
  v_in = (guint8*) GST_VIDEO_FRAME_PLANE_DATA (in_frame, 2);

  width = GST_VIDEO_FRAME_WIDTH (out_frame);
  height = GST_VIDEO_FRAME_HEIGHT (out_frame);
  stride = GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0);

  out_data = (guint32*) GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);

  // GST_INFO ("DEBUG_INFO: rgbtoyuv::transform_frame: ");
  // GST_INFO ("in stride: %d; out stride: %d %d\n", stride, y_stride, uv_stride);

  libyuv::I420ToARGB (y_in, y_stride,
              u_in, uv_stride,
              v_in, uv_stride,
              (guint8*)out_data, stride,
              width, height);

  return GST_FLOW_OK;
}
Exemple #4
0
static void
gst_smpte_blend_i420 (GstVideoFrame * frame1, GstVideoFrame * frame2,
    GstVideoFrame * oframe, GstMask * mask, gint border, gint pos)
{
  guint32 *maskp;
  gint value;
  gint i, j;
  gint min, max;
  guint8 *in1, *in2, *out, *in1u, *in1v, *in2u, *in2v, *outu, *outv;
  gint width, height;

  if (border == 0)
    border++;

  min = pos - border;
  max = pos;

  width = GST_VIDEO_FRAME_WIDTH (frame1);
  height = GST_VIDEO_FRAME_HEIGHT (frame1);

  in1 = GST_VIDEO_FRAME_COMP_DATA (frame1, 0);
  in2 = GST_VIDEO_FRAME_COMP_DATA (frame2, 0);
  out = GST_VIDEO_FRAME_COMP_DATA (oframe, 0);

  in1u = GST_VIDEO_FRAME_COMP_DATA (frame1, 1);
  in1v = GST_VIDEO_FRAME_COMP_DATA (frame1, 2);
  in2u = GST_VIDEO_FRAME_COMP_DATA (frame2, 1);
  in2v = GST_VIDEO_FRAME_COMP_DATA (frame2, 2);
  outu = GST_VIDEO_FRAME_COMP_DATA (oframe, 1);
  outv = GST_VIDEO_FRAME_COMP_DATA (oframe, 2);

  maskp = mask->data;

  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      value = *maskp++;
      value = ((CLAMP (value, min, max) - min) << 8) / border;

      out[j] = ((in1[j] * value) + (in2[j] * (256 - value))) >> 8;
      if (!(i & 1) && !(j & 1)) {
        outu[j / 2] =
            ((in1u[j / 2] * value) + (in2u[j / 2] * (256 - value))) >> 8;
        outv[j / 2] =
            ((in1v[j / 2] * value) + (in2v[j / 2] * (256 - value))) >> 8;
      }
    }

    in1 += GST_VIDEO_FRAME_COMP_STRIDE (frame1, 0);
    in2 += GST_VIDEO_FRAME_COMP_STRIDE (frame2, 0);
    out += GST_VIDEO_FRAME_COMP_STRIDE (oframe, 0);

    if (!(i & 1)) {
      in1u += GST_VIDEO_FRAME_COMP_STRIDE (frame1, 1);
      in2u += GST_VIDEO_FRAME_COMP_STRIDE (frame2, 1);
      in1v += GST_VIDEO_FRAME_COMP_STRIDE (frame1, 2);
      in2v += GST_VIDEO_FRAME_COMP_STRIDE (frame1, 2);
      outu += GST_VIDEO_FRAME_COMP_STRIDE (oframe, 1);
      outv += GST_VIDEO_FRAME_COMP_STRIDE (oframe, 2);
    }
  }
static void
fill_frame_packed8_3 (GstVideoFrame * frame, opj_image_t * image)
{
  gint x, y, w, h;
  guint8 *data_out, *tmp;
  const gint *data_in[3];
  gint dstride;

  w = GST_VIDEO_FRAME_WIDTH (frame);
  h = GST_VIDEO_FRAME_HEIGHT (frame);
  data_out = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
  dstride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);

  data_in[0] = image->comps[0].data;
  data_in[1] = image->comps[1].data;
  data_in[2] = image->comps[2].data;

  for (y = 0; y < h; y++) {
    tmp = data_out;

    for (x = 0; x < w; x++) {
      tmp[1] = *data_in[0];
      tmp[2] = *data_in[1];
      tmp[3] = *data_in[2];

      tmp += 4;
      data_in[0]++;
      data_in[1]++;
      data_in[2]++;
    }
    data_out += dstride;
  }
}
static void
fill_frame_planar16_1 (GstVideoFrame * frame, opj_image_t * image)
{
  gint x, y, w, h;
  guint16 *data_out, *tmp;
  const gint *data_in;
  gint dstride;
  gint shift;

  w = GST_VIDEO_FRAME_WIDTH (frame);
  h = GST_VIDEO_FRAME_HEIGHT (frame);
  data_out = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
  dstride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0) / 2;

  data_in = image->comps[0].data;

  shift = 16 - image->comps[0].prec;

  for (y = 0; y < h; y++) {
    tmp = data_out;

    for (x = 0; x < w; x++) {
      *tmp = *data_in << shift;

      tmp++;
      data_in++;
    }
    data_out += dstride;
  }
}
static void
gst_video_crop_transform_packed_simple (GstVideoCrop * vcrop,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
  guint8 *in_data, *out_data;
  gint width, height;
  guint i, dx;
  gint in_stride, out_stride;

  width = GST_VIDEO_FRAME_WIDTH (out_frame);
  height = GST_VIDEO_FRAME_HEIGHT (out_frame);

  in_data = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
  out_data = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);

  in_stride = GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0);
  out_stride = GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0);

  in_data += vcrop->crop_top * in_stride;
  in_data += vcrop->crop_left * GST_VIDEO_FRAME_COMP_PSTRIDE (in_frame, 0);

  dx = width * GST_VIDEO_FRAME_COMP_PSTRIDE (out_frame, 0);

  for (i = 0; i < height; ++i) {
    memcpy (out_data, in_data, dx);
    in_data += in_stride;
    out_data += out_stride;
  }
}
static void
theora_enc_init_buffer (th_ycbcr_buffer buf, GstVideoFrame * frame)
{
    GstVideoInfo vinfo;
    guint i;

    /* According to Theora developer Timothy Terriberry, the Theora
     * encoder will not use memory outside of pic_width/height, even when
     * the frame size is bigger. The values outside this region will be encoded
     * to default values.
     * Due to this, setting the frame's width/height as the buffer width/height
     * is perfectly ok, even though it does not strictly look ok.
     */

    gst_video_info_init (&vinfo);
    gst_video_info_set_format (&vinfo, GST_VIDEO_FRAME_FORMAT (frame),
                               GST_ROUND_UP_16 (GST_VIDEO_FRAME_WIDTH (frame)),
                               GST_ROUND_UP_16 (GST_VIDEO_FRAME_HEIGHT (frame)));

    for (i = 0; i < 3; i++) {
        buf[i].width = GST_VIDEO_INFO_COMP_WIDTH (&vinfo, i);
        buf[i].height = GST_VIDEO_INFO_COMP_HEIGHT (&vinfo, i);
        buf[i].data = GST_VIDEO_FRAME_COMP_DATA (frame, i);
        buf[i].stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
    }
}
Exemple #9
0
static void
gst_video_balance_packed_rgb (GstVideoBalance * videobalance,
    GstVideoFrame * frame)
{
  gint i, j, height;
  gint width, stride, row_wrap;
  gint pixel_stride;
  guint8 *data;
  gint offsets[3];
  gint r, g, b;
  gint y, u, v;
  gint u_tmp, v_tmp;
  guint8 *tabley = videobalance->tabley;
  guint8 **tableu = videobalance->tableu;
  guint8 **tablev = videobalance->tablev;

  width = GST_VIDEO_FRAME_WIDTH (frame);
  height = GST_VIDEO_FRAME_HEIGHT (frame);

  offsets[0] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 0);
  offsets[1] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 1);
  offsets[2] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 2);

  data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
  stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);

  pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
  row_wrap = stride - pixel_stride * width;

  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      r = data[offsets[0]];
      g = data[offsets[1]];
      b = data[offsets[2]];

      y = APPLY_MATRIX (cog_rgb_to_ycbcr_matrix_8bit_sdtv, 0, r, g, b);
      u_tmp = APPLY_MATRIX (cog_rgb_to_ycbcr_matrix_8bit_sdtv, 1, r, g, b);
      v_tmp = APPLY_MATRIX (cog_rgb_to_ycbcr_matrix_8bit_sdtv, 2, r, g, b);

      y = CLAMP (y, 0, 255);
      u_tmp = CLAMP (u_tmp, 0, 255);
      v_tmp = CLAMP (v_tmp, 0, 255);

      y = tabley[y];
      u = tableu[u_tmp][v_tmp];
      v = tablev[u_tmp][v_tmp];

      r = APPLY_MATRIX (cog_ycbcr_to_rgb_matrix_8bit_sdtv, 0, y, u, v);
      g = APPLY_MATRIX (cog_ycbcr_to_rgb_matrix_8bit_sdtv, 1, y, u, v);
      b = APPLY_MATRIX (cog_ycbcr_to_rgb_matrix_8bit_sdtv, 2, y, u, v);

      data[offsets[0]] = CLAMP (r, 0, 255);
      data[offsets[1]] = CLAMP (g, 0, 255);
      data[offsets[2]] = CLAMP (b, 0, 255);
      data += pixel_stride;
    }
    data += row_wrap;
  }
}
Exemple #10
0
static void
gst_video_balance_packed_yuv (GstVideoBalance * videobalance,
    GstVideoFrame * frame)
{
  gint x, y, stride;
  guint8 *ydata, *udata, *vdata;
  gint yoff, uoff, voff;
  gint width, height;
  gint width2, height2;
  guint8 *tabley = videobalance->tabley;
  guint8 **tableu = videobalance->tableu;
  guint8 **tablev = videobalance->tablev;

  width = GST_VIDEO_FRAME_WIDTH (frame);
  height = GST_VIDEO_FRAME_HEIGHT (frame);

  stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
  ydata = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
  yoff = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);

  for (y = 0; y < height; y++) {
    guint8 *yptr;

    yptr = ydata + y * stride;
    for (x = 0; x < width; x++) {
      *yptr = tabley[*yptr];
      yptr += yoff;
    }
  }

  width2 = GST_VIDEO_FRAME_COMP_WIDTH (frame, 1);
  height2 = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 1);

  udata = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
  vdata = GST_VIDEO_FRAME_COMP_DATA (frame, 2);
  uoff = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 1);
  voff = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 2);

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

    uptr = udata + y * stride;
    vptr = vdata + y * stride;

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

      *uptr = tableu[u1][v1];
      *vptr = tablev[u1][v1];

      uptr += uoff;
      vptr += voff;
    }
  }
}
Exemple #11
0
static void
gst_video_balance_semiplanar_yuv (GstVideoBalance * videobalance,
    GstVideoFrame * frame)
{
  gint x, y;
  guint8 *ydata;
  guint8 *uvdata;
  gint ystride, uvstride;
  gint width, height;
  gint width2, height2;
  guint8 *tabley = videobalance->tabley;
  guint8 **tableu = videobalance->tableu;
  guint8 **tablev = videobalance->tablev;
  gint upos, vpos;

  width = GST_VIDEO_FRAME_WIDTH (frame);
  height = GST_VIDEO_FRAME_HEIGHT (frame);

  ydata = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
  ystride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);

  for (y = 0; y < height; y++) {
    guint8 *yptr;

    yptr = ydata + y * ystride;
    for (x = 0; x < width; x++) {
      *yptr = tabley[*yptr];
      yptr++;
    }
  }

  width2 = GST_VIDEO_FRAME_COMP_WIDTH (frame, 1);
  height2 = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 1);

  uvdata = GST_VIDEO_FRAME_PLANE_DATA (frame, 1);
  uvstride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 1);

  upos = GST_VIDEO_INFO_FORMAT (&frame->info) == GST_VIDEO_FORMAT_NV12 ? 0 : 1;
  vpos = GST_VIDEO_INFO_FORMAT (&frame->info) == GST_VIDEO_FORMAT_NV12 ? 1 : 0;

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

    uvptr = uvdata + y * uvstride;

    for (x = 0; x < width2; x++) {
      u1 = uvptr[upos];
      v1 = uvptr[vpos];

      uvptr[upos] = tableu[u1][v1];
      uvptr[vpos] = tablev[u1][v1];
      uvptr += 2;
    }
  }
}
static opj_image_t *
gst_openjpeg_enc_fill_image (GstOpenJPEGEnc * self, GstVideoFrame * frame)
{
  gint i, ncomps;
  opj_image_cmptparm_t *comps;
  OPJ_COLOR_SPACE colorspace;
  opj_image_t *image;

  ncomps = GST_VIDEO_FRAME_N_COMPONENTS (frame);
  comps = g_new0 (opj_image_cmptparm_t, ncomps);

  for (i = 0; i < ncomps; i++) {
    comps[i].prec = GST_VIDEO_FRAME_COMP_DEPTH (frame, i);
    comps[i].bpp = GST_VIDEO_FRAME_COMP_DEPTH (frame, i);
    comps[i].sgnd = 0;
    comps[i].w = GST_VIDEO_FRAME_COMP_WIDTH (frame, i);
    comps[i].h = GST_VIDEO_FRAME_COMP_HEIGHT (frame, i);
    comps[i].dx =
        GST_VIDEO_FRAME_WIDTH (frame) / GST_VIDEO_FRAME_COMP_WIDTH (frame, i);
    comps[i].dy =
        GST_VIDEO_FRAME_HEIGHT (frame) / GST_VIDEO_FRAME_COMP_HEIGHT (frame, i);
  }

  if ((frame->info.finfo->flags & GST_VIDEO_FORMAT_FLAG_YUV))
    colorspace = OPJ_CLRSPC_SYCC;
  else if ((frame->info.finfo->flags & GST_VIDEO_FORMAT_FLAG_RGB))
    colorspace = OPJ_CLRSPC_SRGB;
  else if ((frame->info.finfo->flags & GST_VIDEO_FORMAT_FLAG_GRAY))
    colorspace = OPJ_CLRSPC_GRAY;
  else
    g_return_val_if_reached (NULL);

  image = opj_image_create (ncomps, comps, colorspace);
  g_free (comps);

  image->x0 = image->y0 = 0;
  image->x1 = GST_VIDEO_FRAME_WIDTH (frame);
  image->y1 = GST_VIDEO_FRAME_HEIGHT (frame);

  self->fill_image (image, frame);

  return image;
}
static void
gst_color_effects_transform_rgb (GstColorEffects * filter,
    GstVideoFrame * frame)
{
  gint i, j;
  gint width, height;
  gint pixel_stride, row_stride, row_wrap;
  guint32 r, g, b;
  guint32 luma;
  gint offsets[3];
  guint8 *data;

  data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
  offsets[0] = GST_VIDEO_FRAME_COMP_POFFSET (frame, 0);
  offsets[1] = GST_VIDEO_FRAME_COMP_POFFSET (frame, 1);
  offsets[2] = GST_VIDEO_FRAME_COMP_POFFSET (frame, 2);

  width = GST_VIDEO_FRAME_WIDTH (frame);
  height = GST_VIDEO_FRAME_HEIGHT (frame);

  row_stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
  pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
  row_wrap = row_stride - pixel_stride * width;

  /* transform */

  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      r = data[offsets[0]];
      g = data[offsets[1]];
      b = data[offsets[2]];
      if (filter->map_luma) {
        /* BT. 709 coefficients in B8 fixed point */
        /* 0.2126 R + 0.7152 G + 0.0722 B */
        luma = ((r << 8) * 54) + ((g << 8) * 183) + ((b << 8) * 19);
        luma >>= 16;            /* get integer part */
        luma *= 3;              /* times 3 to retrieve the correct pixel from
                                 * the lut */
        /* map luma to lookup table */
        /* src.luma |-> table[luma].rgb */
        data[offsets[0]] = filter->table[luma];
        data[offsets[1]] = filter->table[luma + 1];
        data[offsets[2]] = filter->table[luma + 2];
      } else {
        /* map each color component to the correspondent lut color */
        /* src.r |-> table[r].r */
        /* src.g |-> table[g].g */
        /* src.b |-> table[b].b */
        data[offsets[0]] = filter->table[r * 3];
        data[offsets[1]] = filter->table[g * 3 + 1];
        data[offsets[2]] = filter->table[b * 3 + 2];
      }
      data += pixel_stride;
    }
static void
gst_video_crop_transform_packed_complex (GstVideoCrop * vcrop,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
  guint8 *in_data, *out_data;
  guint i, dx;
  gint width, height;
  gint in_stride;
  gint out_stride;

  width = GST_VIDEO_FRAME_WIDTH (out_frame);
  height = GST_VIDEO_FRAME_HEIGHT (out_frame);

  in_data = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
  out_data = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);

  in_stride = GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0);
  out_stride = GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0);

  in_data += vcrop->crop_top * in_stride;

  /* rounding down here so we end up at the start of a macro-pixel and not
   * in the middle of one */
  in_data += ROUND_DOWN_2 (vcrop->crop_left) *
      GST_VIDEO_FRAME_COMP_PSTRIDE (in_frame, 0);

  dx = width * GST_VIDEO_FRAME_COMP_PSTRIDE (out_frame, 0);

  /* UYVY = 4:2:2 - [U0 Y0 V0 Y1] [U2 Y2 V2 Y3] [U4 Y4 V4 Y5]
   * YUYV = 4:2:2 - [Y0 U0 Y1 V0] [Y2 U2 Y3 V2] [Y4 U4 Y5 V4] = YUY2 */
  if ((vcrop->crop_left % 2) != 0) {
    for (i = 0; i < height; ++i) {
      gint j;

      memcpy (out_data, in_data, dx);

      /* move just the Y samples one pixel to the left, don't worry about
       * chroma shift */
      for (j = vcrop->macro_y_off; j < out_stride - 2; j += 2)
        out_data[j] = in_data[j + 2];

      in_data += in_stride;
      out_data += out_stride;
    }
  } else {
    for (i = 0; i < height; ++i) {
      memcpy (out_data, in_data, dx);
      in_data += in_stride;
      out_data += out_stride;
    }
  }
}
Exemple #15
0
static void
gst_jpeg_dec_decode_rgb (GstJpegDec * dec, GstVideoFrame * frame)
{
  guchar *r_rows[16], *g_rows[16], *b_rows[16];
  guchar **scanarray[3] = { r_rows, g_rows, b_rows };
  gint i, j, k;
  gint lines;
  guint8 *base[3];
  guint pstride, rstride;
  gint width, height;

  GST_DEBUG_OBJECT (dec, "indirect decoding of RGB");

  width = GST_VIDEO_FRAME_WIDTH (frame);
  height = GST_VIDEO_FRAME_HEIGHT (frame);

  if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
    return;

  for (i = 0; i < 3; i++)
    base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);

  pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
  rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);

  memcpy (r_rows, dec->idr_y, 16 * sizeof (gpointer));
  memcpy (g_rows, dec->idr_u, 16 * sizeof (gpointer));
  memcpy (b_rows, dec->idr_v, 16 * sizeof (gpointer));

  i = 0;
  while (i < height) {
    lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
    if (G_LIKELY (lines > 0)) {
      for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
        gint p;

        p = 0;
        for (k = 0; k < width; k++) {
          base[0][p] = r_rows[j][k];
          base[1][p] = g_rows[j][k];
          base[2][p] = b_rows[j][k];
          p += pstride;
        }
        base[0] += rstride;
        base[1] += rstride;
        base[2] += rstride;
      }
    } else {
      GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
    }
  }
}
static GstFlowReturn
gst_cairo_overlay_transform_frame_ip (GstVideoFilter * vfilter,
    GstVideoFrame * frame)
{
  GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (vfilter);
  cairo_surface_t *surface;
  cairo_t *cr;
  cairo_format_t format;

  switch (GST_VIDEO_FRAME_FORMAT (frame)) {
    case GST_VIDEO_FORMAT_ARGB:
    case GST_VIDEO_FORMAT_BGRA:
      format = CAIRO_FORMAT_ARGB32;
      break;
    case GST_VIDEO_FORMAT_xRGB:
    case GST_VIDEO_FORMAT_BGRx:
      format = CAIRO_FORMAT_RGB24;
      break;
    case GST_VIDEO_FORMAT_RGB16:
      format = CAIRO_FORMAT_RGB16_565;
      break;
    default:
    {
      GST_WARNING ("No matching cairo format for %s",
          gst_video_format_to_string (GST_VIDEO_FRAME_FORMAT (frame)));
      return GST_FLOW_ERROR;
    }
  }

  surface =
      cairo_image_surface_create_for_data (GST_VIDEO_FRAME_PLANE_DATA (frame,
          0), format, GST_VIDEO_FRAME_WIDTH (frame),
      GST_VIDEO_FRAME_HEIGHT (frame), GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0));

  if (G_UNLIKELY (!surface))
    return GST_FLOW_ERROR;

  cr = cairo_create (surface);
  if (G_UNLIKELY (!cr)) {
    cairo_surface_destroy (surface);
    return GST_FLOW_ERROR;
  }

  g_signal_emit (overlay, gst_cairo_overlay_signals[SIGNAL_DRAW], 0,
      cr, GST_BUFFER_PTS (frame->buffer), GST_BUFFER_DURATION (frame->buffer),
      NULL);

  cairo_destroy (cr);
  cairo_surface_destroy (surface);

  return GST_FLOW_OK;
}
static void
gst_video_crop_transform_planar (GstVideoCrop * vcrop,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
  gint width, height;
  guint8 *y_out, *u_out, *v_out;
  guint8 *y_in, *u_in, *v_in;
  guint i, dx;

  width = GST_VIDEO_FRAME_WIDTH (out_frame);
  height = GST_VIDEO_FRAME_HEIGHT (out_frame);

  /* Y plane */
  y_in = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
  y_out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);

  y_in +=
      (vcrop->crop_top * GST_VIDEO_FRAME_PLANE_STRIDE (in_frame,
          0)) + vcrop->crop_left;
  dx = width;

  for (i = 0; i < height; ++i) {
    memcpy (y_out, y_in, dx);
    y_in += GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0);
    y_out += GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0);
  }

  /* U + V planes */
  u_in = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 1);
  u_out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 1);

  u_in += (vcrop->crop_top / 2) * GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1);
  u_in += vcrop->crop_left / 2;

  v_in = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 2);
  v_out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 2);

  v_in += (vcrop->crop_top / 2) * GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 2);
  v_in += vcrop->crop_left / 2;

  dx = GST_ROUND_UP_2 (width) / 2;

  for (i = 0; i < GST_ROUND_UP_2 (height) / 2; ++i) {
    memcpy (u_out, u_in, dx);
    memcpy (v_out, v_in, dx);
    u_in += GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1);
    u_out += GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 1);
    v_in += GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 2);
    v_out += GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 2);
  }
}
static GstFlowReturn
gst_shagadelictv_transform_frame (GstVideoFilter * vfilter,
                                  GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
    GstShagadelicTV *filter = GST_SHAGADELICTV (vfilter);
    guint32 *src, *dest;
    gint x, y;
    guint32 v;
    guint8 r, g, b;
    gint width, height;

    src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
    dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);

    width = GST_VIDEO_FRAME_WIDTH (in_frame);
    height = GST_VIDEO_FRAME_HEIGHT (in_frame);

    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            v = *src++ | 0x1010100;
            v = (v - 0x707060) & 0x1010100;
            v -= v >> 8;
            /* Try another Babe!
             * v = *src++;
             * *dest++ = v & ((r<<16)|(g<<8)|b);
             */
            r = ((gint8) (filter->ripple[(filter->ry + y) * width * 2 + filter->rx +
                                         x] + filter->phase * 2)) >> 7;
            g = ((gint8) (filter->spiral[y * width + x] + filter->phase * 3)) >> 7;
            b = ((gint8) (filter->ripple[(filter->by + y) * width * 2 + filter->bx +
                                         x] - filter->phase)) >> 7;
            *dest++ = v & ((r << 16) | (g << 8) | b);
        }
    }

    filter->phase -= 8;
    if ((filter->rx + filter->rvx) < 0 || (filter->rx + filter->rvx) >= width)
        filter->rvx = -filter->rvx;
    if ((filter->ry + filter->rvy) < 0 || (filter->ry + filter->rvy) >= height)
        filter->rvy = -filter->rvy;
    if ((filter->bx + filter->bvx) < 0 || (filter->bx + filter->bvx) >= width)
        filter->bvx = -filter->bvx;
    if ((filter->by + filter->bvy) < 0 || (filter->by + filter->bvy) >= height)
        filter->bvy = -filter->bvy;
    filter->rx += filter->rvx;
    filter->ry += filter->rvy;
    filter->bx += filter->bvx;
    filter->by += filter->bvy;

    return GST_FLOW_OK;
}
static GstFlowReturn
gst_video_median_transform_frame (GstVideoFilter * filter,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
  GstVideoMedian *median = GST_VIDEO_MEDIAN (filter);

  if (median->filtersize == 5) {
    median_5 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0),
        GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0),
        GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0),
        GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0),
        GST_VIDEO_FRAME_WIDTH (in_frame), GST_VIDEO_FRAME_HEIGHT (in_frame));

    if (median->lum_only) {
      gst_video_frame_copy_plane (out_frame, in_frame, 1);
      gst_video_frame_copy_plane (out_frame, in_frame, 2);
    } else {
      median_5 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 1),
          GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 1),
          GST_VIDEO_FRAME_PLANE_DATA (in_frame, 1),
          GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1),
          GST_VIDEO_FRAME_WIDTH (in_frame) / 2,
          GST_VIDEO_FRAME_HEIGHT (in_frame) / 2);
      median_5 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 2),
          GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 2),
          GST_VIDEO_FRAME_PLANE_DATA (in_frame, 2),
          GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 2),
          GST_VIDEO_FRAME_WIDTH (in_frame) / 2,
          GST_VIDEO_FRAME_HEIGHT (in_frame) / 2);
    }
  } else {
    median_9 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0),
        GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0),
        GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0),
        GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0),
        GST_VIDEO_FRAME_WIDTH (in_frame), GST_VIDEO_FRAME_HEIGHT (in_frame));

    if (median->lum_only) {
      gst_video_frame_copy_plane (out_frame, in_frame, 1);
      gst_video_frame_copy_plane (out_frame, in_frame, 2);
    } else {
      median_9 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 1),
          GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 1),
          GST_VIDEO_FRAME_PLANE_DATA (in_frame, 1),
          GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1),
          GST_VIDEO_FRAME_WIDTH (in_frame) / 2,
          GST_VIDEO_FRAME_HEIGHT (in_frame) / 2);
      median_9 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 2),
          GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 2),
          GST_VIDEO_FRAME_PLANE_DATA (in_frame, 2),
          GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 2),
          GST_VIDEO_FRAME_WIDTH (in_frame) / 2,
          GST_VIDEO_FRAME_HEIGHT (in_frame) / 2);
    }
  }

  return GST_FLOW_OK;
}
static void
fill_frame_planar16_4_generic (GstVideoFrame * frame, opj_image_t * image)
{
  gint x, y, w, h;
  guint16 *data_out, *tmp;
  const gint *data_in[4];
  gint dstride;
  gint dx[4], dy[4], shift[4];

  w = GST_VIDEO_FRAME_WIDTH (frame);
  h = GST_VIDEO_FRAME_HEIGHT (frame);
  data_out = (guint16 *) GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
  dstride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0) / 2;

  data_in[0] = image->comps[0].data;
  data_in[1] = image->comps[1].data;
  data_in[2] = image->comps[2].data;
  data_in[3] = image->comps[3].data;

  dx[0] = image->comps[0].dx;
  dx[1] = image->comps[1].dx;
  dx[2] = image->comps[2].dx;
  dx[3] = image->comps[3].dx;

  dy[0] = image->comps[0].dy;
  dy[1] = image->comps[1].dy;
  dy[2] = image->comps[2].dy;
  dy[3] = image->comps[3].dy;

  shift[0] = 16 - image->comps[0].prec;
  shift[1] = 16 - image->comps[1].prec;
  shift[2] = 16 - image->comps[2].prec;
  shift[3] = 16 - image->comps[3].prec;

  for (y = 0; y < h; y++) {
    tmp = data_out;

    for (x = 0; x < w; x++) {
      tmp[0] = data_in[3][((y / dy[3]) * w + x) / dx[3]] << shift[3];
      tmp[1] = data_in[0][((y / dy[0]) * w + x) / dx[0]] << shift[0];
      tmp[2] = data_in[1][((y / dy[1]) * w + x) / dx[1]] << shift[1];
      tmp[3] = data_in[2][((y / dy[2]) * w + x) / dx[2]] << shift[2];
      tmp += 4;
    }
    data_out += dstride;
  }
}
Exemple #21
0
static GstFlowReturn
gst_streaktv_transform_frame (GstVideoFilter * vfilter,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
  GstStreakTV *filter = GST_STREAKTV (vfilter);
  guint32 *src, *dest;
  gint i, cf;
  gint video_area, width, height;
  guint32 **planetable = filter->planetable;
  gint plane = filter->plane;
  guint stride_mask, stride_shift, stride;

  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);

  width = GST_VIDEO_FRAME_WIDTH (in_frame);
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);

  video_area = width * height;

  GST_OBJECT_LOCK (filter);
  if (filter->feedback) {
    stride_mask = 0xfcfcfcfc;
    stride = 8;
    stride_shift = 2;
  } else {
    stride_mask = 0xf8f8f8f8;
    stride = 4;
    stride_shift = 3;
  }

  for (i = 0; i < video_area; i++) {
    planetable[plane][i] = (src[i] & stride_mask) >> stride_shift;
  }

  cf = plane & (stride - 1);
  if (filter->feedback) {
    for (i = 0; i < video_area; i++) {
      dest[i] = planetable[cf][i]
          + planetable[cf + stride][i]
          + planetable[cf + stride * 2][i]
          + planetable[cf + stride * 3][i];
      planetable[plane][i] = (dest[i] & stride_mask) >> stride_shift;
    }
  } else {
    for (i = 0; i < video_area; i++) {
Exemple #22
0
static void
gst_smpte_alpha_process_ayuv_ayuv (GstSMPTEAlpha * smpte,
    const GstVideoFrame * in_frame, GstVideoFrame * out_frame, GstMask * mask,
    gint border, gint pos)
{
  gint i, j;
  const guint32 *maskp;
  gint value;
  gint min, max;
  gint width, height;
  guint8 *in, *out;
  gint src_wrap, dest_wrap;

  if (border == 0)
    border++;

  min = pos - border;
  max = pos;
  GST_DEBUG_OBJECT (smpte, "pos %d, min %d, max %d, border %d", pos, min, max,
      border);

  maskp = mask->data;

  width = GST_VIDEO_FRAME_WIDTH (out_frame);
  height = GST_VIDEO_FRAME_HEIGHT (out_frame);

  in = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
  out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
  src_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0) - (width << 2);
  dest_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0) - (width << 2);

  /* we basically copy the source to dest but we scale the alpha channel with
   * the mask */
  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      value = *maskp++;
      *out++ = (*in++ * ((CLAMP (value, min, max) - min) << 8) / border) >> 8;
      *out++ = *in++;
      *out++ = *in++;
      *out++ = *in++;
    }
    in += src_wrap;
    out += dest_wrap;
  }
}
static void
fill_frame_planar8_3_generic (GstVideoFrame * frame, opj_image_t * image)
{
  gint x, y, w, h;
  guint8 *data_out, *tmp;
  const gint *data_in[3];
  gint dstride;
  gint dx[3], dy[3];

  w = GST_VIDEO_FRAME_WIDTH (frame);
  h = GST_VIDEO_FRAME_HEIGHT (frame);
  data_out = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
  dstride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);

  data_in[0] = image->comps[0].data;
  data_in[1] = image->comps[1].data;
  data_in[2] = image->comps[2].data;

  dx[0] = image->comps[0].dx;
  dx[1] = image->comps[1].dx;
  dx[2] = image->comps[2].dx;

  dy[0] = image->comps[0].dy;
  dy[1] = image->comps[1].dy;
  dy[2] = image->comps[2].dy;

  for (y = 0; y < h; y++) {
    tmp = data_out;

    for (x = 0; x < w; x++) {
      tmp[0] = 0xff;
      tmp[1] = data_in[0][((y / dy[0]) * w + x) / dx[0]];
      tmp[2] = data_in[1][((y / dy[1]) * w + x) / dx[1]];
      tmp[3] = data_in[2][((y / dy[2]) * w + x) / dx[2]];
      tmp += 4;
    }
    data_out += dstride;
  }
}
Exemple #24
0
/* Actual processing. */
static GstFlowReturn
gst_burn_transform_frame (GstVideoFilter * vfilter,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
  GstBurn *filter = GST_BURN (vfilter);
  gint video_size, adjustment, width, height;
  guint32 *src, *dest;
  GstClockTime timestamp;
  gint64 stream_time;

  src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
  dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);

  width = GST_VIDEO_FRAME_WIDTH (in_frame);
  height = GST_VIDEO_FRAME_HEIGHT (in_frame);

  video_size = width * height;

  /* GstController: update the properties */
  timestamp = GST_BUFFER_TIMESTAMP (in_frame->buffer);
  stream_time =
      gst_segment_to_stream_time (&GST_BASE_TRANSFORM (filter)->segment,
      GST_FORMAT_TIME, timestamp);

  GST_DEBUG_OBJECT (filter, "sync to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (timestamp));

  if (GST_CLOCK_TIME_IS_VALID (stream_time))
    gst_object_sync_values (GST_OBJECT (filter), stream_time);

  GST_OBJECT_LOCK (filter);
  adjustment = filter->adjustment;
  GST_OBJECT_UNLOCK (filter);

  /*** Now the image processing work.... ***/
  orc_gaudi_burn (dest, src, adjustment, video_size);

  return GST_FLOW_OK;
}
Exemple #25
0
static void
deinterlace_frame_di_greedyh_planar (GstDeinterlaceMethod * method,
    const GstDeinterlaceField * history, guint history_count,
    GstVideoFrame * outframe, int cur_field_idx)
{
  GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (method);
  GstDeinterlaceMethodGreedyHClass *klass =
      GST_DEINTERLACE_METHOD_GREEDY_H_GET_CLASS (self);
  gint InfoIsOdd;
  gint RowStride;
  gint FieldHeight;
  gint Pitch;
  const guint8 *L1;             // ptr to Line1, of 3
  const guint8 *L2;             // ptr to Line2, the weave line
  const guint8 *L3;             // ptr to Line3
  const guint8 *L2P;            // ptr to prev Line2
  guint8 *Dest;
  gint i;
  ScanlineFunction scanline;

  if (cur_field_idx + 2 > history_count || cur_field_idx < 1) {
    GstDeinterlaceMethod *backup_method;

    backup_method = g_object_new (gst_deinterlace_method_linear_get_type (),
        NULL);

    gst_deinterlace_method_setup (backup_method, method->vinfo);
    gst_deinterlace_method_deinterlace_frame (backup_method,
        history, history_count, outframe, cur_field_idx);

    g_object_unref (backup_method);
    return;
  }

  cur_field_idx += 2;

  for (i = 0; i < 3; i++) {
    InfoIsOdd = (history[cur_field_idx - 1].flags == PICTURE_INTERLACED_BOTTOM);
    RowStride = GST_VIDEO_FRAME_PLANE_STRIDE (outframe, i);
    FieldHeight = GST_VIDEO_FRAME_HEIGHT (outframe) / 2;
    Pitch = RowStride * 2;

    if (i == 0)
      scanline = klass->scanline_planar_y;
    else
      scanline = klass->scanline_planar_uv;

    Dest = GST_VIDEO_FRAME_PLANE_DATA (outframe, i);

    L1 = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx - 2].frame, i);
    if (history[cur_field_idx - 2].flags & PICTURE_INTERLACED_BOTTOM)
      L1 += RowStride;

    L2 = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx - 1].frame, i);
    if (history[cur_field_idx - 1].flags & PICTURE_INTERLACED_BOTTOM)
      L2 += RowStride;

    L3 = L1 + Pitch;
    L2P = GST_VIDEO_FRAME_PLANE_DATA (history[cur_field_idx - 3].frame, i);
    if (history[cur_field_idx - 3].flags & PICTURE_INTERLACED_BOTTOM)
      L2P += RowStride;

    deinterlace_frame_di_greedyh_planar_plane (self, L1, L2, L3, L2P, Dest,
        RowStride, FieldHeight, Pitch, InfoIsOdd, scanline);
  }
}
static GstFlowReturn
gst_rsvg_decode_image (GstRsvgDec * rsvg, GstBuffer * buffer,
    GstVideoCodecFrame * frame)
{
  GstVideoDecoder *decoder = GST_VIDEO_DECODER (rsvg);
  GstFlowReturn ret = GST_FLOW_OK;
  cairo_t *cr;
  cairo_surface_t *surface;
  RsvgHandle *handle;
  GError *error = NULL;
  RsvgDimensionData dimension;
  gdouble scalex, scaley;
  GstMapInfo minfo;
  GstVideoFrame vframe;
  GstVideoCodecState *output_state;

  GST_LOG_OBJECT (rsvg, "parsing svg");

  if (!gst_buffer_map (buffer, &minfo, GST_MAP_READ)) {
    GST_ERROR_OBJECT (rsvg, "Failed to get SVG image");
    return GST_FLOW_ERROR;
  }
  handle = rsvg_handle_new_from_data (minfo.data, minfo.size, &error);
  if (!handle) {
    GST_ERROR_OBJECT (rsvg, "Failed to parse SVG image: %s", error->message);
    g_error_free (error);
    return GST_FLOW_ERROR;
  }

  rsvg_handle_get_dimensions (handle, &dimension);

  output_state = gst_video_decoder_get_output_state (decoder);
  if ((output_state == NULL)
      || GST_VIDEO_INFO_WIDTH (&output_state->info) != dimension.width
      || GST_VIDEO_INFO_HEIGHT (&output_state->info) != dimension.height) {

    /* Create the output state */
    if (output_state)
      gst_video_codec_state_unref (output_state);
    output_state =
        gst_video_decoder_set_output_state (decoder, GST_RSVG_VIDEO_FORMAT,
        dimension.width, dimension.height, rsvg->input_state);
  }

  ret = gst_video_decoder_allocate_output_frame (decoder, frame);

  if (ret != GST_FLOW_OK) {
    g_object_unref (handle);
    gst_video_codec_state_unref (output_state);
    GST_ERROR_OBJECT (rsvg, "Buffer allocation failed %s",
        gst_flow_get_name (ret));
    return ret;
  }

  GST_LOG_OBJECT (rsvg, "render image at %d x %d",
      GST_VIDEO_INFO_HEIGHT (&output_state->info),
      GST_VIDEO_INFO_WIDTH (&output_state->info));


  if (!gst_video_frame_map (&vframe,
          &output_state->info, frame->output_buffer, GST_MAP_READWRITE)) {
    GST_ERROR_OBJECT (rsvg, "Failed to get SVG image");
    g_object_unref (handle);
    gst_video_codec_state_unref (output_state);
    return GST_FLOW_ERROR;
  }
  surface =
      cairo_image_surface_create_for_data (GST_VIDEO_FRAME_PLANE_DATA (&vframe,
          0), CAIRO_FORMAT_ARGB32, GST_VIDEO_FRAME_WIDTH (&vframe),
      GST_VIDEO_FRAME_HEIGHT (&vframe), GST_VIDEO_FRAME_PLANE_STRIDE (&vframe,
          0));

  cr = cairo_create (surface);
  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
  cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
  cairo_paint (cr);
  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
  cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);

  scalex = scaley = 1.0;
  if (GST_VIDEO_INFO_WIDTH (&output_state->info) != dimension.width) {
    scalex =
        ((gdouble) GST_VIDEO_INFO_WIDTH (&output_state->info)) /
        ((gdouble) dimension.width);
  }
  if (GST_VIDEO_INFO_HEIGHT (&output_state->info) != dimension.height) {
    scaley =
        ((gdouble) GST_VIDEO_INFO_HEIGHT (&output_state->info)) /
        ((gdouble) dimension.height);
  }
  cairo_scale (cr, scalex, scaley);
  rsvg_handle_render_cairo (handle, cr);

  g_object_unref (handle);
  cairo_destroy (cr);
  cairo_surface_destroy (surface);

  /* Now unpremultiply Cairo's ARGB to match GStreamer's */
  gst_rsvg_decode_unpremultiply (GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0),
      GST_VIDEO_FRAME_WIDTH (&vframe), GST_VIDEO_FRAME_HEIGHT (&vframe));

  gst_video_codec_state_unref (output_state);
  gst_buffer_unmap (buffer, &minfo);
  gst_video_frame_unmap (&vframe);

  return ret;
}
static void
gst_validate_ssim_save_out (GstValidateSsim * self, GstBuffer * buffer,
    const gchar * ref_file, const gchar * file, const gchar * outfolder)
{
  GstVideoFrame frame, converted;

  if (!g_file_test (outfolder, G_FILE_TEST_IS_DIR)) {
    if (g_mkdir_with_parents (outfolder, 0755) != 0) {

      GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR,
          "Could not create output directory %s", outfolder);
      return;
    }
  }

  if (self->priv->outconverter_info.converter == NULL ||
      self->priv->width != self->priv->outconverter_info.out_info.width ||
      self->priv->height != self->priv->outconverter_info.out_info.height) {

    if (self->priv->outconverter_info.converter)
      gst_video_converter_free (self->priv->outconverter_info.converter);

    gst_video_info_init (&self->priv->outconverter_info.in_info);
    gst_video_info_set_format (&self->priv->outconverter_info.in_info,
        GST_VIDEO_FORMAT_GRAY8, self->priv->width, self->priv->height);

    gst_video_info_init (&self->priv->outconverter_info.out_info);
    gst_video_info_set_format (&self->priv->outconverter_info.out_info,
        GST_VIDEO_FORMAT_RGBx, self->priv->width, self->priv->height);

    self->priv->outconverter_info.converter =
        gst_video_converter_new (&self->priv->outconverter_info.in_info,
        &self->priv->outconverter_info.out_info, NULL);
  }

  if (!gst_video_frame_map (&frame, &self->priv->outconverter_info.in_info,
          buffer, GST_MAP_READ)) {
    GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR,
        "Could not map output frame");

    return;
  }

  if (gst_validate_ssim_convert (self, &self->priv->outconverter_info,
          &frame, &converted)) {
    cairo_status_t status;
    cairo_surface_t *surface;
    gchar *bn1 = g_path_get_basename (ref_file);
    gchar *bn2 = g_path_get_basename (file);
    gchar *fname = g_strdup_printf ("%s.VS.%s.result.png", bn1, bn2);
    gchar *outfile = g_build_path (G_DIR_SEPARATOR_S, outfolder, fname, NULL);

    surface =
        cairo_image_surface_create_for_data (GST_VIDEO_FRAME_PLANE_DATA
        (&converted, 0), CAIRO_FORMAT_RGB24, GST_VIDEO_FRAME_WIDTH (&converted),
        GST_VIDEO_FRAME_HEIGHT (&converted),
        GST_VIDEO_FRAME_PLANE_STRIDE (&converted, 0));

    if ((status = cairo_surface_write_to_png (surface, outfile)) !=
        CAIRO_STATUS_SUCCESS) {
      GST_VALIDATE_REPORT (self, GENERAL_INPUT_ERROR,
          "Could not save '%s', cairo status is '%s'", outfile,
          cairo_status_to_string (status));
    }

    cairo_surface_destroy (surface);
    gst_video_frame_unmap (&frame);
    gst_video_frame_unmap (&converted);
    g_free (bn1);
    g_free (bn2);
    g_free (fname);
    g_free (outfile);
  }
}
Exemple #28
0
static GstFlowReturn
gst_zbar_transform_frame_ip (GstVideoFilter * vfilter, GstVideoFrame * frame)
{
  GstZBar *zbar = GST_ZBAR (vfilter);
  gpointer data;
  gint stride, height;
  zbar_image_t *image;
  const zbar_symbol_t *symbol;
  int n;

  image = zbar_image_create ();

  /* all formats we support start with an 8-bit Y plane. zbar doesn't need
   * to know about the chroma plane(s) */
  data = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
  stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
  height = GST_VIDEO_FRAME_HEIGHT (frame);

  zbar_image_set_format (image, GST_MAKE_FOURCC ('Y', '8', '0', '0'));
  zbar_image_set_size (image, stride, height);
  zbar_image_set_data (image, (gpointer) data, stride * height, NULL);

  /* scan the image for barcodes */
  n = zbar_scan_image (zbar->scanner, image);
  if (n == 0)
    goto out;

  /* extract results */
  symbol = zbar_image_first_symbol (image);
  for (; symbol; symbol = zbar_symbol_next (symbol)) {
    zbar_symbol_type_t typ = zbar_symbol_get_type (symbol);
    const char *data = zbar_symbol_get_data (symbol);
    gint quality = zbar_symbol_get_quality (symbol);

    GST_DEBUG_OBJECT (zbar, "decoded %s symbol \"%s\" at quality %d",
        zbar_get_symbol_name (typ), data, quality);

    if (zbar->cache && zbar_symbol_get_count (symbol) != 0)
      continue;

    if (zbar->message) {
      GstMessage *m;
      GstStructure *s;

      /* post a message */
      s = gst_structure_new ("barcode",
          "timestamp", G_TYPE_UINT64, GST_BUFFER_TIMESTAMP (frame->buffer),
          "type", G_TYPE_STRING, zbar_get_symbol_name (typ),
          "symbol", G_TYPE_STRING, data, "quality", G_TYPE_INT, quality, NULL);
      m = gst_message_new_element (GST_OBJECT (zbar), s);
      gst_element_post_message (GST_ELEMENT (zbar), m);
    }
  }

out:
  /* clean up */
  zbar_image_scanner_recycle_image (zbar->scanner, image);
  zbar_image_destroy (image);

  return GST_FLOW_OK;
}
Exemple #29
0
static GstFlowReturn
gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame)
{
  guchar **line[3];             /* the jpeg line buffer         */
  guchar *y[4 * DCTSIZE] = { NULL, };   /* alloc enough for the lines   */
  guchar *u[4 * DCTSIZE] = { NULL, };   /* r_v will be <4               */
  guchar *v[4 * DCTSIZE] = { NULL, };
  gint i, j;
  gint lines, v_samp[3];
  guchar *base[3], *last[3];
  gint stride[3];
  guint height;

  line[0] = y;
  line[1] = u;
  line[2] = v;

  v_samp[0] = dec->cinfo.comp_info[0].v_samp_factor;
  v_samp[1] = dec->cinfo.comp_info[1].v_samp_factor;
  v_samp[2] = dec->cinfo.comp_info[2].v_samp_factor;

  if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2))
    goto format_not_supported;

  height = GST_VIDEO_FRAME_HEIGHT (frame);

  for (i = 0; i < 3; i++) {
    base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
    stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
    /* make sure we don't make jpeglib write beyond our buffer,
     * which might happen if (height % (r_v*DCTSIZE)) != 0 */
    last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
        (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
  }

  /* let jpeglib decode directly into our final buffer */
  GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");

  for (i = 0; i < height; i += v_samp[0] * DCTSIZE) {
    for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) {
      /* Y */
      line[0][j] = base[0] + (i + j) * stride[0];
      if (G_UNLIKELY (line[0][j] > last[0]))
        line[0][j] = last[0];
      /* U */
      if (v_samp[1] == v_samp[0]) {
        line[1][j] = base[1] + ((i + j) / 2) * stride[1];
      } else if (j < (v_samp[1] * DCTSIZE)) {
        line[1][j] = base[1] + ((i / 2) + j) * stride[1];
      }
      if (G_UNLIKELY (line[1][j] > last[1]))
        line[1][j] = last[1];
      /* V */
      if (v_samp[2] == v_samp[0]) {
        line[2][j] = base[2] + ((i + j) / 2) * stride[2];
      } else if (j < (v_samp[2] * DCTSIZE)) {
        line[2][j] = base[2] + ((i / 2) + j) * stride[2];
      }
      if (G_UNLIKELY (line[2][j] > last[2]))
        line[2][j] = last[2];
    }

    lines = jpeg_read_raw_data (&dec->cinfo, line, v_samp[0] * DCTSIZE);
    if (G_UNLIKELY (!lines)) {
      GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
    }
  }
  return GST_FLOW_OK;

format_not_supported:
  {
    gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
        "Unsupported subsampling schema: v_samp factors: %u %u %u",
        v_samp[0], v_samp[1], v_samp[2]);
    return GST_FLOW_ERROR;
  }
}
Exemple #30
0
static void
gst_jpeg_dec_decode_indirect (GstJpegDec * dec, GstVideoFrame * frame, gint r_v,
    gint r_h, gint comp)
{
  guchar *y_rows[16], *u_rows[16], *v_rows[16];
  guchar **scanarray[3] = { y_rows, u_rows, v_rows };
  gint i, j, k;
  gint lines;
  guchar *base[3], *last[3];
  gint stride[3];
  gint width, height;

  GST_DEBUG_OBJECT (dec,
      "unadvantageous width or r_h, taking slow route involving memcpy");

  width = GST_VIDEO_FRAME_WIDTH (frame);
  height = GST_VIDEO_FRAME_HEIGHT (frame);

  if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
    return;

  for (i = 0; i < 3; i++) {
    base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
    stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
    /* make sure we don't make jpeglib write beyond our buffer,
     * which might happen if (height % (r_v*DCTSIZE)) != 0 */
    last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
        (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
  }

  memcpy (y_rows, dec->idr_y, 16 * sizeof (gpointer));
  memcpy (u_rows, dec->idr_u, 16 * sizeof (gpointer));
  memcpy (v_rows, dec->idr_v, 16 * sizeof (gpointer));

  /* fill chroma components for grayscale */
  if (comp == 1) {
    GST_DEBUG_OBJECT (dec, "grayscale, filling chroma");
    for (i = 0; i < 16; i++) {
      memset (u_rows[i], GST_ROUND_UP_32 (width), 0x80);
      memset (v_rows[i], GST_ROUND_UP_32 (width), 0x80);
    }
  }

  for (i = 0; i < height; i += r_v * DCTSIZE) {
    lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
    if (G_LIKELY (lines > 0)) {
      for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
        if (G_LIKELY (base[0] <= last[0])) {
          memcpy (base[0], y_rows[j], stride[0]);
          base[0] += stride[0];
        }
        if (r_v == 2) {
          if (G_LIKELY (base[0] <= last[0])) {
            memcpy (base[0], y_rows[j + 1], stride[0]);
            base[0] += stride[0];
          }
        }
        if (G_LIKELY (base[1] <= last[1] && base[2] <= last[2])) {
          if (r_h == 2) {
            memcpy (base[1], u_rows[k], stride[1]);
            memcpy (base[2], v_rows[k], stride[2]);
          } else if (r_h == 1) {
            hresamplecpy1 (base[1], u_rows[k], stride[1]);
            hresamplecpy1 (base[2], v_rows[k], stride[2]);
          } else {
            /* FIXME: implement (at least we avoid crashing by doing nothing) */
          }
        }

        if (r_v == 2 || (k & 1) != 0) {
          base[1] += stride[1];
          base[2] += stride[2];
        }
      }
    } else {
      GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
    }
  }
}