[gst-devel] I420 Color Space

Dejan Sakelsak sakdean at gmail.com
Sat Nov 1 13:29:29 CET 2008


check this patches out:

http://bugzilla.gnome.org/show_bug.cgi?id=526670

regards,
Dejan

On 10/26/08, Rezek Štěpán <stepan1117 at atlas.cz> wrote:
> Dear gstreamer developers,
>     I have got a question regarding I420 color space or, maybe better said, color spaces in gstreamer in general.
>     I am trying to write a plugin, which will allow to draw anything on video stream using cairo functions. I successfully derived the existing cairotextoverlay plugin and I am changing it to draw anything on cairo surface.
>     One of the problems I am currently challenging is the I420 color space. The existing cairotextoverlay works in a way that it takes cairo
>  overlay in ARGB32 color space, translates it into the I420 color space and than blits in to the current video_frame. This is done in function
>  gst_vector_overlay_push_frame. Everything works fine with one small, but important problem: it translates everything into greyscale, but what I need is to draw colored things on the frame as well.
>     Is there any obvious solution to this problem, or do I have to learn more about color spaces and program that "translation" myself?
>
>  Thank you in advance
>
>  The functions (from plugins-good/ext/cairo/gsttextoverlay.c) are:
>  ********************* code ***************************************
>  static GstFlowReturn gst_vector_overlay_push_frame
>  (GstCairoVectorOverlay * overlay, GstBuffer * video_frame)
>  {
>   guchar *y, *u, *v;
>
>  ...
>   video_frame = gst_buffer_make_writable (video_frame);
>  ...
>
>   y = GST_BUFFER_DATA (video_frame);
>   u = y + I420_U_OFFSET (overlay->width, overlay->height);
>   v = y + I420_V_OFFSET (overlay->width, overlay->height);
>
>   ...
>
>   /* blit text on video image */
>   gst_vector_overlay_blit_1 (overlay,
>       y + (ypos / 1) * I420_Y_ROWSTRIDE (overlay->width),
>       overlay->text_fill_image, 255, I420_Y_ROWSTRIDE (overlay->width));
>   gst_vector_overlay_blit_sub2x2 (overlay,
>       u + (ypos / 2) * I420_U_ROWSTRIDE (overlay->width),
>       overlay->text_fill_image, 128, I420_U_ROWSTRIDE (overlay->width));
>   gst_vector_overlay_blit_sub2x2 (overlay,
>       v + (ypos / 2) * I420_V_ROWSTRIDE (overlay->width),
>       overlay->text_fill_image, 128, I420_V_ROWSTRIDE (overlay->width));
>
>   return gst_pad_push (overlay->srcpad, video_frame);
>  }
>
>  ***************************** code ends ***********************
>  where blit functions are
>
>  ****************************** code ************************
>
>  /* These macros are adapted from videotestsrc.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))
>
>
>  static inline void gst_vector_overlay_blit_1 (GstCairoVectorOverlay *
>  overlay, guchar * dest,
>     guchar * text_image, gint val, guint dest_stride)
>  {
>   gint i, j;
>   gint x, a, y;
>   gint y0 = 0;
>
>   y = val;
>
>   for (i = 0; i < overlay->font_height; i++) {
>     for (j = 0; j < overlay->width; j++) {
>       x = dest[(i + y0) * dest_stride + j];
>       a = text_image[4 * (i * overlay->width + j) + 1];
>       dest[(i + y0) * dest_stride + j] = (y * a + x * (255 - a)) / 255;
>     }
>   }
>  }
>
>  static inline void gst_vector_overlay_blit_sub2x2 (GstCairoVectorOverlay
>  * overlay, guchar * dest,
>     guchar * text_image, gint val, guint dest_stride)
>  {
>   gint i, j;
>   gint x, a, y;
>   gint y0 = 0;
>
>   y = val;
>
>   for (i = 0; i < overlay->font_height; i += 2) {
>     for (j = 0; j < overlay->width; j += 2) {
>       x = dest[(i / 2 + y0) * dest_stride + j / 2];
>       a = (text_image[4 * (i * overlay->width + j) + 1] +
>           text_image[4 * (i * overlay->width + j + 1) + 1] +
>           text_image[4 * ((i + 1) * overlay->width + j) + 1] +
>           text_image[4 * ((i + 1) * overlay->width + j + 1) + 1] + 2) / 4;
>       dest[(i / 2 + y0) * dest_stride + j / 2] = (y * a + x * (255 - a))
>  / 255;
>     }
>   }
>  }
>
>
>
> -------------------------------------------------------------------------
>  This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
>  Build the coolest Linux based applications with Moblin SDK & win great prizes
>  Grand prize is a trip for two to an Open Source event anywhere in the world
>  http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
>  gstreamer-devel mailing list
>  gstreamer-devel at lists.sourceforge.net
>  https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
>
>


More information about the gstreamer-devel mailing list