handle stride correctly
authorThomas Vander Stichele <thomas@apestaart.org>
Tue, 27 Jul 2004 15:59:10 +0000 (15:59 +0000)
committerThomas Vander Stichele <thomas@apestaart.org>
Tue, 27 Jul 2004 15:59:10 +0000 (15:59 +0000)
Original commit message from CVS:
handle stride correctly

ChangeLog
gst/ffmpegcolorspace/gstffmpegcolorspace.c
gst/ffmpegcolorspace/imgconvert.c

index e1ad294..7097321 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2004-07-27  Thomas Vander Stichele  <thomas at apestaart dot org>
 
+       * gst/ffmpegcolorspace/gstffmpegcolorspace.c:
+       (gst_ffmpegcolorspace_class_init), (gst_ffmpegcolorspace_chain):
+       * gst/ffmpegcolorspace/imgconvert.c: (avpicture_fill):
+         handle stride, needs work if we want to move stride handling
+         upstream, but works correctly for our purposes.
+
+2004-07-27  Thomas Vander Stichele  <thomas at apestaart dot org>
+
        * gst/videoscale/README:
          add testing examples
        * gst/videoscale/gstvideoscale.c: (gst_videoscale_link),
index dfbdbba..b318334 100644 (file)
@@ -28,6 +28,9 @@
 
 #include "gstffmpegcodecmap.h"
 
+GST_DEBUG_CATEGORY (ffmpegcolorspace_debug);
+#define GST_CAT_DEFAULT ffmpegcolorspace_debug
+
 #define GST_TYPE_FFMPEGCOLORSPACE \
   (gst_ffmpegcolorspace_get_type())
 #define GST_FFMPEGCOLORSPACE(obj) \
@@ -280,6 +283,9 @@ gst_ffmpegcolorspace_class_init (GstFFMpegColorspaceClass * klass)
   gobject_class->get_property = gst_ffmpegcolorspace_get_property;
 
   gstelement_class->change_state = gst_ffmpegcolorspace_change_state;
+
+  GST_DEBUG_CATEGORY_INIT (ffmpegcolorspace_debug, "ffmpegcolorspace", 0,
+      "FFMPEG-based colorspace converter");
 }
 
 static void
@@ -339,19 +345,30 @@ gst_ffmpegcolorspace_chain (GstPad * pad, GstData * data)
     outbuf = inbuf;
   } else {
     /* use bufferpool here */
+    AVPicture *from_p, *to_p;
+
     guint size = avpicture_get_size (space->to_pixfmt,
         space->width,
         space->height);
 
+    GST_LOG_OBJECT (space, "convert from format %d, %dx%d, buffer size %d",
+        space->from_pixfmt, space->width, space->height,
+        GST_BUFFER_SIZE (inbuf));
+    GST_LOG_OBJECT (space, "convert to format %d, %dx%d, buffer size %d",
+        space->to_pixfmt, space->width, space->height, size);
+
     outbuf = gst_pad_alloc_buffer (space->srcpad, GST_BUFFER_OFFSET_NONE, size);
 
     /* convert */
-    avpicture_fill ((AVPicture *) & space->from_frame, GST_BUFFER_DATA (inbuf),
+#define ROUND_UP_4(x) (((x) + 3) & ~3)
+    from_p = &(space->from_frame);
+    avpicture_fill (from_p, GST_BUFFER_DATA (inbuf),
         space->from_pixfmt, space->width, space->height);
-    avpicture_fill ((AVPicture *) & space->to_frame, GST_BUFFER_DATA (outbuf),
+    to_p = &(space->to_frame);
+    avpicture_fill (to_p, GST_BUFFER_DATA (outbuf),
         space->to_pixfmt, space->width, space->height);
-    img_convert ((AVPicture *) & space->to_frame, space->to_pixfmt,
-        (AVPicture *) & space->from_frame, space->from_pixfmt,
+
+    img_convert (to_p, space->to_pixfmt, from_p, space->from_pixfmt,
         space->width, space->height);
 
     GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf);
index 4452647..2d685a7 100644 (file)
@@ -280,6 +280,7 @@ avcodec_get_pix_fmt (const char *name)
   return i;
 }
 
+#ifdef FFMPEG_NOSTRIDE
 /* Picture field are filled with 'ptr' addresses. Also return size */
 int
 avpicture_fill (AVPicture * picture, uint8_t * ptr,
@@ -360,6 +361,109 @@ avpicture_fill (AVPicture * picture, uint8_t * ptr,
   }
 }
 
+#else
+/* Sets bytes per video line and plane pointers, taking stride into account.
+ * Stride for each format is the expected image line size rounded up by 4.
+ * FIXME: instead of hardcoding here, set the default strides in the picture
+ * definition and allow caller to override first. */
+#define ROUND_UP_4(x) (((x) + 3) & ~3)
+int
+avpicture_fill (AVPicture * picture, uint8_t * ptr,
+    int pix_fmt, int width, int height)
+{
+  int size, w2, h2, size2;
+  int stride, stride2;
+  PixFmtInfo *pinfo;
+
+  pinfo = &pix_fmt_info[pix_fmt];
+  stride = ROUND_UP_4 (width);
+  size = stride * height;
+  switch (pix_fmt) {
+    case PIX_FMT_YUV420P:
+    case PIX_FMT_YUV422P:
+    case PIX_FMT_YUV444P:
+    case PIX_FMT_YUV410P:
+    case PIX_FMT_YUV411P:
+    case PIX_FMT_YUVJ420P:
+    case PIX_FMT_YUVJ422P:
+    case PIX_FMT_YUVJ444P:
+      stride = ROUND_UP_4 (width);
+      size = stride * height;
+      w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
+      stride2 = ROUND_UP_4 (w2);
+      h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
+      size2 = stride2 * h2;
+      picture->data[0] = ptr;
+      picture->data[1] = picture->data[0] + size;
+      picture->data[2] = picture->data[1] + size2;
+      picture->linesize[0] = stride;
+      picture->linesize[1] = stride2;
+      picture->linesize[2] = stride2;
+      return size + 2 * size2;
+    case PIX_FMT_RGB24:
+    case PIX_FMT_BGR24:
+      stride = ROUND_UP_4 (width * 3);
+      size = stride * height;
+      picture->data[0] = ptr;
+      picture->data[1] = NULL;
+      picture->data[2] = NULL;
+      picture->linesize[0] = stride;
+      return size;
+    case PIX_FMT_RGBA32:
+      stride = width * 4;
+      size = stride * height;
+      picture->data[0] = ptr;
+      picture->data[1] = NULL;
+      picture->data[2] = NULL;
+      picture->linesize[0] = stride;
+      return size;
+    case PIX_FMT_RGB555:
+    case PIX_FMT_RGB565:
+    case PIX_FMT_YUV422:
+      stride = ROUND_UP_4 (width * 2);
+      size = stride * height;
+      picture->data[0] = ptr;
+      picture->data[1] = NULL;
+      picture->data[2] = NULL;
+      picture->linesize[0] = stride;
+      return size;
+    case PIX_FMT_GRAY8:
+      stride = ROUND_UP_4 (width);
+      size = stride * height;
+      picture->data[0] = ptr;
+      picture->data[1] = NULL;
+      picture->data[2] = NULL;
+      picture->linesize[0] = stride;
+      return size;
+    case PIX_FMT_MONOWHITE:
+    case PIX_FMT_MONOBLACK:
+      stride = ROUND_UP_4 ((width + 7) >> 3);
+      size = stride * height;
+      picture->data[0] = ptr;
+      picture->data[1] = NULL;
+      picture->data[2] = NULL;
+      picture->linesize[0] = stride;
+      return size;
+    case PIX_FMT_PAL8:
+      /* already forced to be with stride, so same result as other function */
+      stride = ROUND_UP_4 (width);
+      size = stride * height;
+      picture->data[0] = ptr;
+      picture->data[1] = ptr + size;    /* palette is stored here as 256 32 bit words */
+      picture->data[2] = NULL;
+      picture->linesize[0] = stride;
+      picture->linesize[1] = 4;
+      return size + 256 * 4;
+    default:
+      picture->data[0] = NULL;
+      picture->data[1] = NULL;
+      picture->data[2] = NULL;
+      picture->data[3] = NULL;
+      return -1;
+  }
+}
+#endif
+
 int
 avpicture_layout (const AVPicture * src, int pix_fmt, int width, int height,
     unsigned char *dest, int dest_size)