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); }
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; } }