videotestsrc: subsample chroma before packing
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 17 May 2013 14:26:49 +0000 (16:26 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 27 May 2013 09:05:08 +0000 (11:05 +0200)
Run the chroma subsampler before packing.

gst/videotestsrc/gstvideotestsrc.c
gst/videotestsrc/gstvideotestsrc.h
gst/videotestsrc/videotestsrc.c
gst/videotestsrc/videotestsrc.h

index 83efa60..66ecc5e 100644 (file)
@@ -656,6 +656,9 @@ gst_video_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
   const GstStructure *structure;
   GstVideoTestSrc *videotestsrc;
   GstVideoInfo info;
+  guint i;
+  guint n_lines;
+  gint offset;
 
   videotestsrc = GST_VIDEO_TEST_SRC (bsrc);
 
@@ -685,6 +688,31 @@ gst_video_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
     videotestsrc->y_invert = y_inv;
   }
 
+  /* create chroma subsampler */
+  if (videotestsrc->subsample)
+    gst_video_chroma_resample_free (videotestsrc->subsample);
+  videotestsrc->subsample = gst_video_chroma_resample_new (0,
+      info.chroma_site, 0, info.finfo->unpack_format, -info.finfo->w_sub[2],
+      -info.finfo->h_sub[2]);
+
+  for (i = 0; i < videotestsrc->n_lines; i++)
+    g_free (videotestsrc->lines[i]);
+  g_free (videotestsrc->lines);
+
+  if (videotestsrc->subsample != NULL) {
+    gst_video_chroma_resample_get_info (videotestsrc->subsample,
+        &n_lines, &offset);
+  } else {
+    n_lines = 1;
+    offset = 0;
+  }
+
+  videotestsrc->lines = g_malloc (sizeof (gpointer) * n_lines);
+  for (i = 0; i < n_lines; i++)
+    videotestsrc->lines[i] = g_malloc ((info.width + 16) * 8);
+  videotestsrc->n_lines = n_lines;
+  videotestsrc->offset = offset;
+
   /* looks ok here */
   videotestsrc->info = info;
 
@@ -914,6 +942,9 @@ gst_video_test_src_stop (GstBaseSrc * basesrc)
   src->tmpline_u8 = NULL;
   g_free (src->tmpline_u16);
   src->tmpline_u16 = NULL;
+  if (src->subsample)
+    gst_video_chroma_resample_free (src->subsample);
+  src->subsample = NULL;
 
   return TRUE;
 }
index 22080b7..a836104 100644 (file)
@@ -124,6 +124,7 @@ struct _GstVideoTestSrc {
 
   /* video state */
   GstVideoInfo info;
+  GstVideoChromaResample *subsample;
   gboolean bayer;
   gint x_invert;
   gint y_invert;
@@ -168,6 +169,10 @@ struct _GstVideoTestSrc {
   guint8 *tmpline;
   guint8 *tmpline2;
   guint16 *tmpline_u16;
+
+  guint n_lines;
+  gint offset;
+  gpointer *lines;
 };
 
 struct _GstVideoTestSrcClass {
index 2835f84..8aabf2a 100644 (file)
@@ -197,6 +197,9 @@ videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h)
   p->tmpline2 = v->tmpline2;
   p->tmpline_u8 = v->tmpline_u8;
   p->tmpline_u16 = v->tmpline_u16;
+  p->n_lines = v->n_lines;
+  p->offset = v->offset;
+  p->lines = v->lines;
   p->x_offset = (v->horizontal_speed * v->n_frames) % width;
   if (p->x_offset < 0)
     p->x_offset += width;
@@ -243,6 +246,7 @@ videotestsrc_setup_paintinfo (GstVideoTestSrc * v, paintinfo * p, int w, int h)
   }
   p->background_color.gray = RGB_TO_Y (r, g, b);
 
+  p->subsample = v->subsample;
 }
 
 static void
@@ -1134,13 +1138,24 @@ static void
 convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y)
 {
   const GstVideoFormatInfo *finfo, *uinfo;
-  gint i, width = GST_VIDEO_FRAME_WIDTH (frame);
-  gpointer src;
+  gint line, offset, i, width, height, bits;
+  guint n_lines;
+  gpointer dest;
 
   finfo = frame->info.finfo;
   uinfo = gst_video_format_get_info (finfo->unpack_format);
 
-  if (GST_VIDEO_FORMAT_INFO_DEPTH (uinfo, 0) == 16) {
+  width = GST_VIDEO_FRAME_WIDTH (frame);
+  height = GST_VIDEO_FRAME_HEIGHT (frame);
+
+  bits = GST_VIDEO_FORMAT_INFO_DEPTH (uinfo, 0);
+
+  n_lines = p->n_lines;
+  offset = p->offset;
+  line = y % n_lines;
+  dest = p->lines[line];
+
+  if (bits == 16) {
     /* 16 bits */
     for (i = 0; i < width; i++) {
       p->tmpline_u16[i * 4 + 0] = TO_16 (p->tmpline[i * 4 + 0]);
@@ -1148,13 +1163,34 @@ convert_hline_generic (paintinfo * p, GstVideoFrame * frame, int y)
       p->tmpline_u16[i * 4 + 2] = TO_16 (p->tmpline[i * 4 + 2]);
       p->tmpline_u16[i * 4 + 3] = TO_16 (p->tmpline[i * 4 + 3]);
     }
-    src = p->tmpline_u16;
+    memcpy (dest, p->tmpline_u16, width * 8);
   } else {
-    src = p->tmpline;
+    memcpy (dest, p->tmpline, width * 4);
+  }
+
+  if (line - offset == n_lines - 1) {
+    gpointer lines[8];
+    guint idx;
+
+    y -= n_lines - 1;
+
+    for (i = 0; i < n_lines; i++) {
+      idx = CLAMP (y + i + offset, 0, height);
+
+      GST_DEBUG ("line %d, %d, idx %d", i, y + i + offset, idx);
+      lines[i] = p->lines[idx % n_lines];
+    }
+
+    if (p->subsample)
+      gst_video_chroma_resample (p->subsample, lines, width);
+
+    for (i = 0; i < n_lines; i++) {
+      GST_DEBUG ("pack line %d", y + i + offset);
+      finfo->pack_func (finfo, GST_VIDEO_PACK_FLAG_NONE,
+          lines[i], 0, frame->data, frame->info.stride,
+          frame->info.chroma_site, y + i + offset, width);
+    }
   }
-  finfo->pack_func (finfo, GST_VIDEO_PACK_FLAG_NONE,
-      src, 0, frame->data, frame->info.stride,
-      frame->info.chroma_site, y, width);
 }
 
 static void
index 1136524..6a69c8c 100644 (file)
@@ -39,6 +39,7 @@ struct paintinfo_struct
   void (*paint_tmpline) (paintinfo * p, int x, int w);
   void (*convert_tmpline) (paintinfo * p, GstVideoFrame *frame, int y);
   void (*convert_hline) (paintinfo * p, GstVideoFrame *frame, int y);
+  GstVideoChromaResample *subsample;
   int x_offset;
 
   int x_invert;
@@ -49,6 +50,10 @@ struct paintinfo_struct
   guint8 *tmpline_u8;
   guint16 *tmpline_u16;
 
+  guint n_lines;
+  gint offset;
+  gpointer *lines;
+
   struct vts_color_struct foreground_color;
   struct vts_color_struct background_color;
 };