diff options
author | Tim-Philipp Müller <tim@centricular.net> | 2005-10-28 15:11:18 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.net> | 2005-10-28 15:11:18 +0000 |
commit | a8ef411492acbf114cc7282369c6ad34de4e7dc3 (patch) | |
tree | f565993dedaecfa320e26889198e84a548019f19 /ext | |
parent | 64997b7f510a22cec0c14a1ab729111a3485267f (diff) | |
download | gst-plugins-bad-a8ef411492acbf114cc7282369c6ad34de4e7dc3.tar.gz gst-plugins-bad-a8ef411492acbf114cc7282369c6ad34de4e7dc3.tar.bz2 gst-plugins-bad-a8ef411492acbf114cc7282369c6ad34de4e7dc3.zip |
ext/sdl/sdlvideosink.*: Fix I420 output on some machines (not very nice, but should work).
Original commit message from CVS:
* ext/sdl/sdlvideosink.c: (gst_sdlvideosink_base_init),
(gst_sdlvideosink_class_init),
(gst_sdlvideosink_get_sdl_from_fourcc), (gst_sdlvideosink_setcaps),
(gst_sdlvideosink_show_frame):
* ext/sdl/sdlvideosink.h:
Fix I420 output on some machines (not very nice, but should work).
Add an 'sdlvideosink' debug category. Disable formats that do
not work. Fix some vararg function issues.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/sdl/sdlvideosink.c | 74 | ||||
-rw-r--r-- | ext/sdl/sdlvideosink.h | 4 |
2 files changed, 59 insertions, 19 deletions
diff --git a/ext/sdl/sdlvideosink.c b/ext/sdl/sdlvideosink.c index 69b6c887..0fb562c7 100644 --- a/ext/sdl/sdlvideosink.c +++ b/ext/sdl/sdlvideosink.c @@ -32,6 +32,21 @@ #include "sdlvideosink.h" +GST_DEBUG_CATEGORY_STATIC (sdlvideosink_debug); +#define GST_CAT_DEFAULT sdlvideosink_debug + +/* These macros are adapted from videotestsrc.c + * and/or gst-plugins/gst/games/gstvideoimage.c */ +#define I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width)) +#define I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2) +#define I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(I420_Y_ROWSTRIDE(width)))/2) + +#define I420_Y_OFFSET(w,h) (0) +#define I420_U_OFFSET(w,h) (I420_Y_OFFSET(w,h)+(I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h))) +#define I420_V_OFFSET(w,h) (I420_U_OFFSET(w,h)+(I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2)) + +#define I420_SIZE(w,h) (I420_V_OFFSET(w,h)+(I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2)) + /* elementfactory information */ static GstElementDetails gst_sdlvideosink_details = { "Video sink", @@ -124,22 +139,26 @@ gst_sdlvideosink_base_init (gpointer g_class) GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); GstCaps *capslist; gint i; - gulong format[6] = { GST_MAKE_FOURCC ('I', '4', '2', '0'), + guint32 formats[] = { + GST_MAKE_FOURCC ('I', '4', '2', '0'), GST_MAKE_FOURCC ('Y', 'V', '1', '2'), - GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'), + GST_MAKE_FOURCC ('Y', 'U', 'Y', '2') +/* GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'), GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y') +*/ }; /* make a list of all available caps */ capslist = gst_caps_new_empty (); - for (i = 0; i < 5; i++) { + for (i = 0; i < G_N_ELEMENTS (formats); i++) { gst_caps_append_structure (capslist, gst_structure_new ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, format[i], + "format", GST_TYPE_FOURCC, formats[i], "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, - "framerate", GST_TYPE_DOUBLE_RANGE, 1.0, 100.0, NULL)); + "framerate", GST_TYPE_DOUBLE_RANGE, (gdouble) 1.0, + (gdouble) 100.0, NULL)); } sink_template = gst_pad_template_new ("sink", @@ -147,6 +166,9 @@ gst_sdlvideosink_base_init (gpointer g_class) gst_element_class_add_pad_template (element_class, sink_template); gst_element_class_set_details (element_class, &gst_sdlvideosink_details); + + GST_DEBUG_CATEGORY_INIT (sdlvideosink_debug, "sdlvideosink", 0, + "SDL video sink element"); } static void @@ -189,7 +211,7 @@ gst_sdlvideosink_class_init (GstSDLVideoSinkClass * klass) gstelement_class = (GstElementClass *) klass; gstvs_class = (GstBaseSinkClass *) klass; - parent_class = g_type_class_ref (GST_TYPE_BASE_SINK); + parent_class = g_type_class_peek_parent (klass); gobject_class->set_property = gst_sdlvideosink_set_property; gobject_class->get_property = gst_sdlvideosink_get_property; @@ -337,8 +359,9 @@ gst_sdlvideosink_get_sdl_from_fourcc (GstSDLVideoSink * sdlvideosink, guint32 code) { switch (code) { + /* Note: SDL_IYUV_OVERLAY does not always work for I420 */ case GST_MAKE_FOURCC ('I', '4', '2', '0'): - return SDL_IYUV_OVERLAY; + return SDL_YV12_OVERLAY; case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): return SDL_YV12_OVERLAY; case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): @@ -544,9 +567,9 @@ gst_sdlvideosink_setcaps (GstBaseSink * bsink, GstCaps * vscapslist) sdlvideosink = GST_SDLVIDEOSINK (bsink); structure = gst_caps_get_structure (vscapslist, 0); - gst_structure_get_fourcc (structure, "format", &format); + gst_structure_get_fourcc (structure, "format", &sdlvideosink->fourcc); sdlvideosink->format = - gst_sdlvideosink_get_sdl_from_fourcc (sdlvideosink, format); + gst_sdlvideosink_get_sdl_from_fourcc (sdlvideosink, sdlvideosink->fourcc); gst_structure_get_int (structure, "width", &sdlvideosink->width); gst_structure_get_int (structure, "height", &sdlvideosink->height); gst_structure_get_double (structure, "framerate", &sdlvideosink->framerate); @@ -574,21 +597,36 @@ gst_sdlvideosink_show_frame (GstBaseSink * bsink, GstBuffer * buf) !sdlvideosink->overlay || !sdlvideosink->overlay->pixels) goto not_init; - if (GST_BUFFER_DATA (buf) != sdlvideosink->overlay->pixels[0]) { + /* if (GST_BUFFER_DATA (buf) != sdlvideosink->overlay->pixels[0]) */ + if (TRUE) { if (!gst_sdlvideosink_lock (sdlvideosink)) goto cannot_lock; /* buf->yuv - FIXME: bufferpool! */ - if (sdlvideosink->format == SDL_IYUV_OVERLAY || - sdlvideosink->format == SDL_YV12_OVERLAY) { - memcpy (sdlvideosink->overlay->pixels[0], GST_BUFFER_DATA (buf), + 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 + sdlvideosink->width * sdlvideosink->height; + v = y + sdlvideosink->width * sdlvideosink->height * 5 / 4; + break; + default: + g_assert_not_reached (); + } + + memcpy (sdlvideosink->overlay->pixels[0], y, sdlvideosink->width * sdlvideosink->height); - memcpy (sdlvideosink->overlay->pixels[1], - GST_BUFFER_DATA (buf) + sdlvideosink->width * sdlvideosink->height, + memcpy (sdlvideosink->overlay->pixels[1], u, sdlvideosink->width * sdlvideosink->height / 4); - memcpy (sdlvideosink->overlay->pixels[2], - GST_BUFFER_DATA (buf) + - sdlvideosink->width * sdlvideosink->height * 5 / 4, + memcpy (sdlvideosink->overlay->pixels[2], v, sdlvideosink->width * sdlvideosink->height / 4); } else { memcpy (sdlvideosink->overlay->pixels[0], GST_BUFFER_DATA (buf), diff --git a/ext/sdl/sdlvideosink.h b/ext/sdl/sdlvideosink.h index eaf0e9ee..5e3984b5 100644 --- a/ext/sdl/sdlvideosink.h +++ b/ext/sdl/sdlvideosink.h @@ -49,7 +49,9 @@ typedef struct _GstSDLVideoSinkClass GstSDLVideoSinkClass; struct _GstSDLVideoSink { GstVideoSink videosink; - guint32 format; + guint32 format; /* the SDL format */ + guint32 fourcc; /* our fourcc from the caps */ + gint width, height; /* the size of the incoming YUV stream */ unsigned long xwindow_id; |