theora: Split out buffer resize in its own function
authorBenjamin Otte <otte@gnome.org>
Fri, 4 Sep 2009 14:49:08 +0000 (16:49 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 9 Sep 2009 14:45:54 +0000 (16:45 +0200)
ext/theora/theoraenc.c

index f7ab79c..2618dbd 100644 (file)
@@ -752,6 +752,141 @@ theora_enc_is_discontinuous (GstTheoraEnc * enc, GstClockTime timestamp,
   return ret;
 }
 
+static GstBuffer *
+theora_enc_resize_buffer (GstTheoraEnc * enc, GstBuffer * buffer)
+{
+  GstBuffer *newbuf;
+  gint i;
+  guchar *dest_y, *src_y;
+  guchar *dest_u, *src_u;
+  guchar *dest_v, *src_v;
+  gint src_y_stride, src_uv_stride;
+  gint dst_y_stride, dst_uv_stride;
+  gint width, height;
+  gint cwidth, cheight;
+  gint offset_x, right_x, right_border;
+  gint y_size;
+
+  if (enc->width == enc->info_width && enc->height == enc->info_height) {
+    GST_LOG_OBJECT (enc, "no cropping/conversion needed");
+    return buffer;
+  }
+
+  GST_LOG_OBJECT (enc, "cropping/conversion needed for strides");
+  /* source width/height */
+  width = enc->width;
+  height = enc->height;
+  /* soucre chroma width/height */
+  cwidth = width / 2;
+  cheight = height / 2;
+
+  /* source strides as defined in videotestsrc */
+  src_y_stride = GST_ROUND_UP_4 (width);
+  src_uv_stride = GST_ROUND_UP_8 (width) / 2;
+
+  /* destination strides from the real picture width */
+  dst_y_stride = enc->info_width;
+  dst_uv_stride = enc->info_width / 2;
+
+  y_size = enc->info_width * enc->info_height;
+
+  newbuf = gst_buffer_new_and_alloc (y_size * 3 / 2);
+  if (!newbuf) {
+    gst_buffer_unref (buffer);
+    return NULL;
+  }
+  GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET_NONE;
+  gst_buffer_set_caps (newbuf, GST_PAD_CAPS (enc->srcpad));
+
+  dest_y = GST_BUFFER_DATA (newbuf);
+  dest_u = dest_y + y_size;
+  dest_v = dest_u + y_size / 4;
+
+  src_y = GST_BUFFER_DATA (buffer);
+  src_u = src_y + src_y_stride * GST_ROUND_UP_2 (height);
+  src_v = src_u + src_uv_stride * GST_ROUND_UP_2 (height) / 2;
+
+  if (enc->border != BORDER_NONE) {
+    /* fill top border */
+    for (i = 0; i < enc->offset_y; i++) {
+      memset (dest_y, 0, dst_y_stride);
+      dest_y += dst_y_stride;
+    }
+  } else {
+    dest_y += dst_y_stride * enc->offset_y;
+  }
+
+  offset_x = enc->offset_x;
+  right_x = width + enc->offset_x;
+  right_border = dst_y_stride - right_x;
+
+  /* copy Y plane */
+  for (i = 0; i < height; i++) {
+    memcpy (dest_y + offset_x, src_y, width);
+    if (enc->border != BORDER_NONE) {
+      memset (dest_y, 0, offset_x);
+      memset (dest_y + right_x, 0, right_border);
+    }
+
+    dest_y += dst_y_stride;
+    src_y += src_y_stride;
+  }
+
+  if (enc->border != BORDER_NONE) {
+    /* fill bottom border */
+    for (i = height + enc->offset_y; i < enc->info.height; i++) {
+      memset (dest_y, 0, dst_y_stride);
+      dest_y += dst_y_stride;
+    }
+
+    /* fill top border chroma */
+    for (i = 0; i < enc->offset_y / 2; i++) {
+      memset (dest_u, 128, dst_uv_stride);
+      memset (dest_v, 128, dst_uv_stride);
+      dest_u += dst_uv_stride;
+      dest_v += dst_uv_stride;
+    }
+  } else {
+    dest_u += dst_uv_stride * enc->offset_y / 2;
+    dest_v += dst_uv_stride * enc->offset_y / 2;
+  }
+
+  offset_x = enc->offset_x / 2;
+  right_x = cwidth + offset_x;
+  right_border = dst_uv_stride - right_x;
+
+  /* copy UV planes */
+  for (i = 0; i < cheight; i++) {
+    memcpy (dest_v + offset_x, src_v, cwidth);
+    memcpy (dest_u + offset_x, src_u, cwidth);
+
+    if (enc->border != BORDER_NONE) {
+      memset (dest_u, 128, offset_x);
+      memset (dest_u + right_x, 128, right_border);
+      memset (dest_v, 128, offset_x);
+      memset (dest_v + right_x, 128, right_border);
+    }
+
+    dest_u += dst_uv_stride;
+    dest_v += dst_uv_stride;
+    src_u += src_uv_stride;
+    src_v += src_uv_stride;
+  }
+
+  if (enc->border != BORDER_NONE) {
+    /* fill bottom border */
+    for (i = cheight + enc->offset_y / 2; i < enc->info_height / 2; i++) {
+      memset (dest_u, 128, dst_uv_stride);
+      memset (dest_v, 128, dst_uv_stride);
+      dest_u += dst_uv_stride;
+      dest_v += dst_uv_stride;
+    }
+  }
+
+  gst_buffer_unref (buffer);
+  return newbuf;
+}
+
 static GstFlowReturn
 theora_enc_chain (GstPad * pad, GstBuffer * buffer)
 {
@@ -922,138 +1057,15 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
 
     y_size = enc->info_width * enc->info_height;
 
-    if (enc->width == enc->info_width && enc->height == enc->info_height) {
-      GST_LOG_OBJECT (enc, "no cropping/conversion needed");
-      /* easy case, no cropping/conversion needed */
-      pixels = GST_BUFFER_DATA (buffer);
-
-      yuv.y = pixels;
-      yuv.u = yuv.y + y_size;
-      yuv.v = yuv.u + y_size / 4;
-    } else {
-      GstBuffer *newbuf;
-      gint i;
-      guchar *dest_y, *src_y;
-      guchar *dest_u, *src_u;
-      guchar *dest_v, *src_v;
-      gint src_y_stride, src_uv_stride;
-      gint dst_y_stride, dst_uv_stride;
-      gint width, height;
-      gint cwidth, cheight;
-      gint offset_x, right_x, right_border;
-
-      GST_LOG_OBJECT (enc, "cropping/conversion needed for strides");
-      /* source width/height */
-      width = enc->width;
-      height = enc->height;
-      /* soucre chroma width/height */
-      cwidth = width / 2;
-      cheight = height / 2;
-
-      /* source strides as defined in videotestsrc */
-      src_y_stride = GST_ROUND_UP_4 (width);
-      src_uv_stride = GST_ROUND_UP_8 (width) / 2;
-
-      /* destination strides from the real picture width */
-      dst_y_stride = enc->info_width;
-      dst_uv_stride = enc->info_width / 2;
-
-      newbuf = gst_buffer_new_and_alloc (y_size * 3 / 2);
-      if (!newbuf) {
-        ret = GST_FLOW_ERROR;
-        goto no_buffer;
-      }
-      GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET_NONE;
-      gst_buffer_set_caps (newbuf, GST_PAD_CAPS (enc->srcpad));
-
-      dest_y = yuv.y = GST_BUFFER_DATA (newbuf);
-      dest_u = yuv.u = yuv.y + y_size;
-      dest_v = yuv.v = yuv.u + y_size / 4;
-
-      src_y = GST_BUFFER_DATA (buffer);
-      src_u = src_y + src_y_stride * GST_ROUND_UP_2 (height);
-      src_v = src_u + src_uv_stride * GST_ROUND_UP_2 (height) / 2;
-
-      if (enc->border != BORDER_NONE) {
-        /* fill top border */
-        for (i = 0; i < enc->offset_y; i++) {
-          memset (dest_y, 0, dst_y_stride);
-          dest_y += dst_y_stride;
-        }
-      } else {
-        dest_y += dst_y_stride * enc->offset_y;
-      }
-
-      offset_x = enc->offset_x;
-      right_x = width + enc->offset_x;
-      right_border = dst_y_stride - right_x;
-
-      /* copy Y plane */
-      for (i = 0; i < height; i++) {
-        memcpy (dest_y + offset_x, src_y, width);
-        if (enc->border != BORDER_NONE) {
-          memset (dest_y, 0, offset_x);
-          memset (dest_y + right_x, 0, right_border);
-        }
+    buffer = theora_enc_resize_buffer (enc, buffer);
+    if (buffer == NULL)
+      return GST_FLOW_ERROR;
 
-        dest_y += dst_y_stride;
-        src_y += src_y_stride;
-      }
+    pixels = GST_BUFFER_DATA (buffer);
 
-      if (enc->border != BORDER_NONE) {
-        /* fill bottom border */
-        for (i = height + enc->offset_y; i < enc->info.height; i++) {
-          memset (dest_y, 0, dst_y_stride);
-          dest_y += dst_y_stride;
-        }
-
-        /* fill top border chroma */
-        for (i = 0; i < enc->offset_y / 2; i++) {
-          memset (dest_u, 128, dst_uv_stride);
-          memset (dest_v, 128, dst_uv_stride);
-          dest_u += dst_uv_stride;
-          dest_v += dst_uv_stride;
-        }
-      } else {
-        dest_u += dst_uv_stride * enc->offset_y / 2;
-        dest_v += dst_uv_stride * enc->offset_y / 2;
-      }
-
-      offset_x = enc->offset_x / 2;
-      right_x = cwidth + offset_x;
-      right_border = dst_uv_stride - right_x;
-
-      /* copy UV planes */
-      for (i = 0; i < cheight; i++) {
-        memcpy (dest_v + offset_x, src_v, cwidth);
-        memcpy (dest_u + offset_x, src_u, cwidth);
-
-        if (enc->border != BORDER_NONE) {
-          memset (dest_u, 128, offset_x);
-          memset (dest_u + right_x, 128, right_border);
-          memset (dest_v, 128, offset_x);
-          memset (dest_v + right_x, 128, right_border);
-        }
-
-        dest_u += dst_uv_stride;
-        dest_v += dst_uv_stride;
-        src_u += src_uv_stride;
-        src_v += src_uv_stride;
-      }
-
-      if (enc->border != BORDER_NONE) {
-        /* fill bottom border */
-        for (i = cheight + enc->offset_y / 2; i < enc->info_height / 2; i++) {
-          memset (dest_u, 128, dst_uv_stride);
-          memset (dest_v, 128, dst_uv_stride);
-          dest_u += dst_uv_stride;
-          dest_v += dst_uv_stride;
-        }
-      }
-
-      gst_buffer_unref (buffer);
-      buffer = newbuf;
-    }
+    yuv.y = pixels;
+    yuv.u = yuv.y + y_size;
+    yuv.v = yuv.u + y_size / 4;
 
     if (theora_enc_is_discontinuous (enc, running_time, duration)) {
       theora_enc_reset (enc);
@@ -1099,10 +1111,6 @@ header_push:
     gst_buffer_unref (buffer);
     return ret;
   }
-no_buffer:
-  {
-    return ret;
-  }
 data_push:
   {
     gst_buffer_unref (buffer);