static void
fill_i420 (guint8 * data, gint width, gint height, gint color)
{
  gint size = I420_Y_ROWSTRIDE (width) * GST_ROUND_UP_2 (height);
  gint size4 = size >> 2;
  guint8 *yp = data;
  guint8 *up = data + I420_U_OFFSET (width, height);
  guint8 *vp = data + I420_V_OFFSET (width, height);

  memset (yp, y_colors[color], size);
  memset (up, u_colors[color], size4);
  memset (vp, v_colors[color], size4);
}
Пример #2
0
static GstFlowReturn
gst_sdlvideosink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
{

  GstSDLVideoSink *sdlvideosink;

  sdlvideosink = GST_SDLVIDEOSINK (bsink);

  g_mutex_lock (sdlvideosink->lock);
  if (!sdlvideosink->init ||
      !sdlvideosink->overlay || !sdlvideosink->overlay->pixels)
    goto not_init;

  /* if (GST_BUFFER_DATA (buf) != sdlvideosink->overlay->pixels[0]) */
  if (TRUE) {
    guint8 *out;
    gint l;

    if (!gst_sdlvideosink_lock (sdlvideosink))
      goto cannot_lock;

    /* buf->yuv - FIXME: bufferpool! */
    if (sdlvideosink->format == SDL_YV12_OVERLAY) {
      guint8 *y, *u, *v;

      switch (sdlvideosink->fourcc) {
        case GST_MAKE_FOURCC ('I', '4', '2', '0'):
          y = GST_BUFFER_DATA (buf);
          /* I420 is YV12 with switched colour planes and different offsets */
          v = y + I420_U_OFFSET (sdlvideosink->width, sdlvideosink->height);
          u = y + I420_V_OFFSET (sdlvideosink->width, sdlvideosink->height);
          break;
        case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
          y = GST_BUFFER_DATA (buf);
          u = y + I420_U_OFFSET (sdlvideosink->width, sdlvideosink->height);
          v = y + I420_V_OFFSET (sdlvideosink->width, sdlvideosink->height);
          break;
        default:
          gst_sdlvideosink_unlock (sdlvideosink);
          g_mutex_unlock (sdlvideosink->lock);
          g_return_val_if_reached (GST_FLOW_ERROR);
      }

      /* Y Plane */
      out = sdlvideosink->overlay->pixels[0];
      for (l = 0; l < sdlvideosink->height; l++) {
        memcpy (out, y, I420_Y_ROWSTRIDE (sdlvideosink->width));
        out += sdlvideosink->overlay->pitches[0];
        y += I420_Y_ROWSTRIDE (sdlvideosink->width);
      }

      /* U plane */
      out = sdlvideosink->overlay->pixels[1];
      for (l = 0; l < (sdlvideosink->height / 2); l++) {
        memcpy (out, u, I420_U_ROWSTRIDE (sdlvideosink->width));
        out += sdlvideosink->overlay->pitches[1];
        u += I420_U_ROWSTRIDE (sdlvideosink->width);
      }

      /* V plane */
      out = sdlvideosink->overlay->pixels[2];
      for (l = 0; l < (sdlvideosink->height / 2); l++) {
        memcpy (out, v, I420_V_ROWSTRIDE (sdlvideosink->width));
        out += sdlvideosink->overlay->pitches[2];
        v += I420_V_ROWSTRIDE (sdlvideosink->width);
      }
    } else {
      guint8 *in = GST_BUFFER_DATA (buf);
      gint in_stride = sdlvideosink->width * 2;

      out = sdlvideosink->overlay->pixels[0];

      for (l = 0; l < sdlvideosink->height; l++) {
        memcpy (out, in, in_stride);
        out += sdlvideosink->overlay->pitches[0];
        in += in_stride;
      }
    }
    gst_sdlvideosink_unlock (sdlvideosink);
  }

  /* Show, baby, show! */
  SDL_DisplayYUVOverlay (sdlvideosink->overlay, &(sdlvideosink->rect));

  /* Handle any resize */
  gst_sdlv_process_events (sdlvideosink);

  g_mutex_unlock (sdlvideosink->lock);

  return GST_FLOW_OK;

  /* ERRORS */
not_init:
  {
    GST_ELEMENT_ERROR (sdlvideosink, CORE, NEGOTIATION, (NULL),
        ("not negotiated."));
    g_mutex_unlock (sdlvideosink->lock);
    return GST_FLOW_NOT_NEGOTIATED;
  }
cannot_lock:
  {
    /* lock function posted detailed message */
    g_mutex_unlock (sdlvideosink->lock);
    return GST_FLOW_ERROR;
  }
}