summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gst/videocrop/gstvideocrop.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
index d2f2c67d..d96061a0 100644
--- a/gst/videocrop/gstvideocrop.c
+++ b/gst/videocrop/gstvideocrop.c
@@ -277,53 +277,70 @@ gst_video_crop_sink_connect (GstPad *pad, GstCaps *caps)
return GST_PAD_LINK_OK;
}
+#define GST_VIDEO_I420_SIZE(width,height) ((width)*(height) + ((width)/2)*((height)/2)*2)
+
+#define GST_VIDEO_I420_Y_OFFSET(width,height) (0)
+#define GST_VIDEO_I420_U_OFFSET(width,height) ((width)*(height))
+#define GST_VIDEO_I420_V_OFFSET(width,height) ((width)*(height) + ((width/2)*(height/2)))
+
+#define GST_VIDEO_I420_Y_ROWSTRIDE(width) (width)
+#define GST_VIDEO_I420_U_ROWSTRIDE(width) ((width)/2)
+#define GST_VIDEO_I420_V_ROWSTRIDE(width) ((width)/2)
+
static void
gst_video_crop_i420 (GstVideoCrop *video_crop, GstBuffer *src_buffer, GstBuffer *dest_buffer)
{
+ guint8 *src;
+ guint8 *dest;
guint8 *srcY, *srcU, *srcV;
guint8 *destY, *destU, *destV;
gint out_width = video_crop->width -
(video_crop->crop_left + video_crop->crop_right);
gint out_height = video_crop->height -
(video_crop->crop_top + video_crop->crop_bottom);
- gint src_stride = video_crop->width;
- gint src_size = video_crop->width * video_crop->height;
+ gint src_stride;
gint j;
- srcY = GST_BUFFER_DATA (src_buffer) +
- (src_stride * video_crop->crop_top + video_crop->crop_left);
- destY = GST_BUFFER_DATA (dest_buffer);
+ src = GST_BUFFER_DATA (src_buffer);
+ dest = GST_BUFFER_DATA (dest_buffer);
+
+ g_return_if_fail(GST_BUFFER_SIZE (dest_buffer) == GST_VIDEO_I420_SIZE(out_width,out_height));
+
+ srcY = src + GST_VIDEO_I420_Y_OFFSET(video_crop->width, video_crop->height);
+ destY = dest + GST_VIDEO_I420_Y_OFFSET(out_width, out_height);
+
+ src_stride = GST_VIDEO_I420_Y_ROWSTRIDE(video_crop->width);
/* copy Y plane first */
+ srcY += src_stride * video_crop->crop_top + video_crop->crop_left;
for (j = 0; j < out_height; j++) {
memcpy (destY, srcY, out_width);
srcY += src_stride;
destY += out_width;
}
- out_width >>= 1;
- src_stride >>= 1;
- out_height >>= 1;
+ src_stride = GST_VIDEO_I420_U_ROWSTRIDE(video_crop->width);
- destU = destY;
- destV = destU + ((out_width * out_height) >> 1);
+ destU = dest + GST_VIDEO_I420_U_OFFSET(out_width, out_height);
+ destV = dest + GST_VIDEO_I420_V_OFFSET(out_width, out_height);
- srcU = GST_BUFFER_DATA (src_buffer) + src_size +
- ((src_stride * video_crop->crop_top + video_crop->crop_left) >> 1);
- srcV = srcU + (src_size >> 2);
+ srcU = src + GST_VIDEO_I420_U_OFFSET(video_crop->width, video_crop->height);
+ srcV = src + GST_VIDEO_I420_V_OFFSET(video_crop->width, video_crop->height);
- /* copy U plane */
- for (j = 0; j < out_height; j++) {
- memcpy (destU, srcU, out_width);
+ srcU += src_stride * (video_crop->crop_top/2) + (video_crop->crop_left/2);
+ srcV += src_stride * (video_crop->crop_top/2) + (video_crop->crop_left/2);
+
+ for (j = 0; j < out_height/2; j++) {
+ /* copy U plane */
+ memcpy (destU, srcU, out_width/2);
srcU += src_stride;
- destU += out_width;
- }
- /* copy U plane */
- for (j = 0; j < out_height; j++) {
- memcpy (destV, srcV, out_width);
+ destU += out_width/2;
+
+ /* copy V plane */
+ memcpy (destV, srcV, out_width/2);
srcV += src_stride;
- destV += out_width;
+ destV += out_width/2;
}
}