summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2012-11-08 17:51:00 +0100
committerOlivier CrĂȘte <olivier.crete@collabora.com>2012-11-10 02:40:28 +0100
commit3175a5d82211bd87b6280abfa048f153f2fa440f (patch)
treeb201a0374a7f71dabe6c1475e76f5aaadb5cd6c4
parent42ec3552f2dfd77e0e83663369e78838c0463ab6 (diff)
videocrop: Add support for NV12/NV21
https://bugzilla.gnome.org/show_bug.cgi?id=687965
-rw-r--r--gst/videocrop/gstvideocrop.c50
-rw-r--r--gst/videocrop/gstvideocrop.h6
-rw-r--r--tests/check/elements/videocrop.c10
3 files changed, 65 insertions, 1 deletions
diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
index 082ca1184..a6b4562d8 100644
--- a/gst/videocrop/gstvideocrop.c
+++ b/gst/videocrop/gstvideocrop.c
@@ -102,6 +102,8 @@ enum
GST_VIDEO_CAPS_YUV ("Y800") ";" \
GST_VIDEO_CAPS_YUV ("I420") ";" \
GST_VIDEO_CAPS_YUV ("YV12") ";" \
+ GST_VIDEO_CAPS_YUV ("NV12") ";" \
+ GST_VIDEO_CAPS_YUV ("NV21") ";" \
GST_VIDEO_CAPS_RGB_16 ";" \
GST_VIDEO_CAPS_RGB_15 ";" \
GST_VIDEO_CAPS_GRAY
@@ -327,6 +329,15 @@ gst_video_crop_get_image_details_from_caps (GstVideoCrop * vcrop,
details->size = details->v_off +
details->v_stride * (GST_ROUND_UP_2 (height) / 2);
break;
+ case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
+ case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
+ details->packing = VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR;
+ details->y_stride = GST_ROUND_UP_4 (width);
+ details->uv_stride = details->y_stride;
+ details->y_off = 0;
+ details->uv_off = details->y_stride * GST_ROUND_UP_2 (height);
+ details->size = details->y_stride * GST_ROUND_UP_2 (height) * 3 / 2;
+ break;
}
default:
goto unknown_format;
@@ -480,6 +491,42 @@ gst_video_crop_transform_planar (GstVideoCrop * vcrop, GstBuffer * inbuf,
}
}
+static void
+gst_video_crop_transform_semi_planar (GstVideoCrop * vcrop, GstBuffer * inbuf,
+ GstBuffer * outbuf)
+{
+ guint8 *y_out, *uv_out;
+ guint8 *y_in, *uv_in;
+ guint i, dx;
+
+ /* Y plane */
+ y_in = GST_BUFFER_DATA (inbuf);
+ y_out = GST_BUFFER_DATA (outbuf);
+
+ y_in += vcrop->crop_top * vcrop->in.y_stride + vcrop->crop_left;
+ dx = vcrop->out.width;
+
+ for (i = 0; i < vcrop->out.height; ++i) {
+ memcpy (y_out, y_in, dx);
+ y_in += vcrop->in.y_stride;
+ y_out += vcrop->out.y_stride;
+ }
+
+ /* UV plane */
+ uv_in = GST_BUFFER_DATA (inbuf) + vcrop->in.uv_off;
+ uv_out = GST_BUFFER_DATA (outbuf) + vcrop->out.uv_off;
+
+ uv_in += (vcrop->crop_top / 2) * vcrop->in.uv_stride;
+ uv_in += GST_ROUND_DOWN_2 (vcrop->crop_left);
+ dx = GST_ROUND_UP_2 (vcrop->out.width);
+
+ for (i = 0; i < GST_ROUND_UP_2 (vcrop->out.height) / 2; i++) {
+ memcpy (uv_out, uv_in, dx);
+ uv_in += vcrop->in.uv_stride;
+ uv_out += vcrop->out.uv_stride;
+ }
+}
+
static GstFlowReturn
gst_video_crop_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer * outbuf)
@@ -496,6 +543,9 @@ gst_video_crop_transform (GstBaseTransform * trans, GstBuffer * inbuf,
case VIDEO_CROP_PIXEL_FORMAT_PLANAR:
gst_video_crop_transform_planar (vcrop, inbuf, outbuf);
break;
+ case VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR:
+ gst_video_crop_transform_semi_planar (vcrop, inbuf, outbuf);
+ break;
default:
g_assert_not_reached ();
}
diff --git a/gst/videocrop/gstvideocrop.h b/gst/videocrop/gstvideocrop.h
index d13ca9b2d..994b73dba 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;
@@ -60,6 +61,9 @@ struct _GstVideoCropImageDetails
guint y_stride, y_off;
guint u_stride, u_off;
guint v_stride, v_off;
+
+ /* For bi-planar UV or VU plane */
+ guint uv_stride, uv_off;
};
typedef struct _GstVideoCrop GstVideoCrop;
diff --git a/tests/check/elements/videocrop.c b/tests/check/elements/videocrop.c
index 9f68e9575..fd0d6381d 100644
--- a/tests/check/elements/videocrop.c
+++ b/tests/check/elements/videocrop.c
@@ -281,6 +281,16 @@ check_1x1_buffer (GstBuffer * buf)
fail_unless_equals_int (GST_BUFFER_DATA (buf)[3], 240);
/* no chroma planes */
break;
+ case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
+ fail_unless_equals_int (GST_BUFFER_DATA (buf)[0], 81);
+ fail_unless_equals_int (GST_BUFFER_DATA (buf)[8], 90);
+ fail_unless_equals_int (GST_BUFFER_DATA (buf)[9], 240);
+ break;
+ case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
+ fail_unless_equals_int (GST_BUFFER_DATA (buf)[0], 81);
+ fail_unless_equals_int (GST_BUFFER_DATA (buf)[8], 240);
+ fail_unless_equals_int (GST_BUFFER_DATA (buf)[9], 90);
+ break;
default:
GST_LOG ("not checking %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (format));
break;