summaryrefslogtreecommitdiff
path: root/gst/videocrop
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2012-11-09 13:27:16 +0100
committerOlivier CrĂȘte <olivier.crete@collabora.com>2012-11-10 01:52:44 +0100
commite111068f7bd348c34082da2513f527185547e892 (patch)
treeb896d528c2526eb40995290122454a7f221d7b51 /gst/videocrop
parent8a4a6b770fd86fcf1cb17e9015aa384ab191bbb4 (diff)
downloadgstreamer-plugins-good-e111068f7bd348c34082da2513f527185547e892.tar.gz
videocrop: Add NV12/NV21 support
https://bugzilla.gnome.org/show_bug.cgi?id=687964
Diffstat (limited to 'gst/videocrop')
-rw-r--r--gst/videocrop/gstvideocrop.c50
-rw-r--r--gst/videocrop/gstvideocrop.h3
2 files changed, 51 insertions, 2 deletions
diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
index eeac54887..dc18c2bbb 100644
--- a/gst/videocrop/gstvideocrop.c
+++ b/gst/videocrop/gstvideocrop.c
@@ -80,7 +80,7 @@ enum
#define VIDEO_CROP_CAPS \
GST_VIDEO_CAPS_MAKE ("{ RGBx, xRGB, BGRx, xBGR, " \
"RGBA, ARGB, BGRA, ABGR, RGB, BGR, AYUV, YUY2, " \
- "YVYU, UYVY, I420, RGB16, RGB15, GRAY8 }")
+ "YVYU, UYVY, I420, RGB16, RGB15, GRAY8, NV12, NV21 }")
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
@@ -373,6 +373,47 @@ gst_video_crop_transform_planar (GstVideoCrop * vcrop,
}
}
+static void
+gst_video_crop_transform_semi_planar (GstVideoCrop * vcrop,
+ GstVideoFrame * in_frame, GstVideoFrame * out_frame)
+{
+ gint width, height;
+ guint8 *y_out, *uv_out;
+ guint8 *y_in, *uv_in;
+ guint i, dx;
+
+ width = GST_VIDEO_FRAME_WIDTH (out_frame);
+ height = GST_VIDEO_FRAME_HEIGHT (out_frame);
+
+ /* Y plane */
+ y_in = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
+ y_out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
+
+ /* UV plane */
+ uv_in = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 1);
+ uv_out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 1);
+
+ y_in += vcrop->crop_top * GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0) +
+ vcrop->crop_left;
+ dx = width;
+
+ for (i = 0; i < height; ++i) {
+ memcpy (y_out, y_in, dx);
+ y_in += GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0);
+ y_out += GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0);
+ }
+
+ uv_in += (vcrop->crop_top / 2) * GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1);
+ uv_in += GST_ROUND_DOWN_2 (vcrop->crop_left);
+ dx = GST_ROUND_UP_2 (width);
+
+ for (i = 0; i < GST_ROUND_UP_2 (height) / 2; i++) {
+ memcpy (uv_out, uv_in, dx);
+ uv_in += GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1);
+ uv_out += GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 1);
+ }
+}
+
static GstFlowReturn
gst_video_crop_transform_frame (GstVideoFilter * vfilter,
GstVideoFrame * in_frame, GstVideoFrame * out_frame)
@@ -390,6 +431,9 @@ gst_video_crop_transform_frame (GstVideoFilter * vfilter,
case VIDEO_CROP_PIXEL_FORMAT_PLANAR:
gst_video_crop_transform_planar (vcrop, in_frame, out_frame);
break;
+ case VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR:
+ gst_video_crop_transform_semi_planar (vcrop, in_frame, out_frame);
+ break;
default:
g_assert_not_reached ();
}
@@ -657,6 +701,10 @@ gst_video_crop_set_info (GstVideoFilter * vfilter, GstCaps * in,
case GST_VIDEO_FORMAT_YV12:
crop->packing = VIDEO_CROP_PIXEL_FORMAT_PLANAR;
break;
+ case GST_VIDEO_FORMAT_NV12:
+ case GST_VIDEO_FORMAT_NV21:
+ crop->packing = VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR;
+ break;
default:
goto unknown_format;
}
diff --git a/gst/videocrop/gstvideocrop.h b/gst/videocrop/gstvideocrop.h
index 346e9bcab..cd8ad06c5 100644
--- a/gst/videocrop/gstvideocrop.h
+++ b/gst/videocrop/gstvideocrop.h
@@ -38,7 +38,8 @@ G_BEGIN_DECLS
typedef enum {
VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE = 0, /* RGBx, AYUV */
VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX, /* UYVY, YVYU */
- VIDEO_CROP_PIXEL_FORMAT_PLANAR /* I420, YV12 */
+ VIDEO_CROP_PIXEL_FORMAT_PLANAR, /* I420, YV12 */
+ VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR /* NV12, NV21 */
} VideoCropPixelFormat;
typedef struct _GstVideoCropImageDetails GstVideoCropImageDetails;