video-format: handle x offset in unpack
authorWim Taymans <wtaymans@redhat.com>
Thu, 27 Nov 2014 12:01:03 +0000 (13:01 +0100)
committerWim Taymans <wtaymans@redhat.com>
Thu, 27 Nov 2014 12:01:03 +0000 (13:01 +0100)
Add support for x offset in almost all unpack methods.
Fix naming of source and dest pixels.
Add const to source pixels.

gst-libs/gst/video/video-format.c

index c971ac3..20317b3 100644 (file)
@@ -81,12 +81,24 @@ unpack_planar_420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   gint uv = GET_UV_420 (y, flags);
-  guint8 *y_line = GET_Y_LINE (y);
-  guint8 *u_line = GET_U_LINE (uv);
-  guint8 *v_line = GET_V_LINE (uv);
-  guint8 *ayuv = dest;
+  const guint8 *sy = GET_Y_LINE (y);
+  const guint8 *su = GET_U_LINE (uv);
+  const guint8 *sv = GET_V_LINE (uv);
+  guint8 *d = dest;
+
+  sy += x;
+  su += x >> 1;
+  sv += x >> 1;
 
-  video_orc_unpack_I420 (ayuv, y_line, u_line, v_line, width);
+  if (x & 1) {
+    d[0] = 0xff;
+    d[1] = *sy++;
+    d[2] = *su++;
+    d[3] = *sv++;
+    width--;
+    d += 4;
+  }
+  video_orc_unpack_I420 (d, sy, su, sv, width);
 }
 
 static void
@@ -96,24 +108,24 @@ pack_planar_420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   gint uv = GET_UV_420 (y, flags);
-  guint8 *y_line = GET_Y_LINE (y);
-  guint8 *u_line = GET_U_LINE (uv);
-  guint8 *v_line = GET_V_LINE (uv);
-  const guint8 *ayuv = src;
+  guint8 *dy = GET_Y_LINE (y);
+  guint8 *du = GET_U_LINE (uv);
+  guint8 *dv = GET_V_LINE (uv);
+  const guint8 *s = src;
 
   if (IS_CHROMA_LINE_420 (y, flags)) {
-    g_return_if_fail (IS_ALIGNED (src, 8));
+    g_return_if_fail (IS_ALIGNED (s, 8));
 
-    video_orc_pack_I420 (y_line, u_line, v_line, src, width / 2);
+    video_orc_pack_I420 (dy, du, dv, s, width / 2);
     if (width & 1) {
       gint i = width - 1;
 
-      y_line[i] = ayuv[i * 4 + 1];
-      u_line[i >> 1] = ayuv[i * 4 + 2];
-      v_line[i >> 1] = ayuv[i * 4 + 3];
+      dy[i] = s[i * 4 + 1];
+      du[i >> 1] = s[i * 4 + 2];
+      dv[i >> 1] = s[i * 4 + 3];
     }
   } else
-    video_orc_pack_Y (y_line, src, width);
+    video_orc_pack_Y (dy, s, width);
 }
 
 #define PACK_YUY2 GST_VIDEO_FORMAT_AYUV, unpack_YUY2, 1, pack_YUY2
@@ -122,20 +134,31 @@ unpack_YUY2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  guint8 *line = GET_LINE (y);
+  const guint8 *s = GET_LINE (y);
   guint8 *d = dest;
 
-  g_return_if_fail (IS_ALIGNED (dest, 8));
+  s += (x & ~1) << 1;
+  if (x & 1) {
+    d[0] = 0xff;
+    d[1] = s[2];
+    d[2] = s[1];
+    d[3] = s[3];
+    s += 4;
+    d += 4;
+    width--;
+  }
+
+  g_return_if_fail (IS_ALIGNED (d, 8));
 
-  video_orc_unpack_YUY2 (dest, line, width / 2);
+  video_orc_unpack_YUY2 (d, s, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
     d[i * 4 + 0] = 0xff;
-    d[i * 4 + 1] = line[i * 2 + 0];
-    d[i * 4 + 2] = line[i * 2 + 1];
-    d[i * 4 + 3] = line[i * 2 + 3];
+    d[i * 4 + 1] = s[i * 2 + 0];
+    d[i * 4 + 2] = s[i * 2 + 1];
+    d[i * 4 + 3] = s[i * 2 + 3];
   }
 }
 
@@ -145,19 +168,19 @@ pack_YUY2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  guint8 *line = GET_LINE (y);
-  const guint8 *ayuv = src;
+  guint8 *d = GET_LINE (y);
+  const guint8 *s = src;
 
-  g_return_if_fail (IS_ALIGNED (src, 8));
+  g_return_if_fail (IS_ALIGNED (s, 8));
 
-  video_orc_pack_YUY2 (line, src, width / 2);
+  video_orc_pack_YUY2 (d, s, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
-    line[i * 2 + 0] = ayuv[i * 4 + 1];
-    line[i * 2 + 1] = ayuv[i * 4 + 2];
-    line[i * 2 + 3] = ayuv[i * 4 + 3];
+    d[i * 2 + 0] = s[i * 4 + 1];
+    d[i * 2 + 1] = s[i * 4 + 2];
+    d[i * 2 + 3] = s[i * 4 + 3];
   }
 }
 
@@ -167,20 +190,31 @@ unpack_UYVY (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  guint8 *line = GET_LINE (y);
+  const guint8 *s = GET_LINE (y);
   guint8 *d = dest;
 
-  g_return_if_fail (IS_ALIGNED (dest, 8));
+  s += (x & ~1) << 1;
+  if (x & 1) {
+    d[0] = 0xff;
+    d[1] = s[3];
+    d[2] = s[0];
+    d[3] = s[2];
+    s += 4;
+    d += 4;
+    width--;
+  }
+
+  g_return_if_fail (IS_ALIGNED (d, 8));
 
-  video_orc_unpack_UYVY (dest, line, width / 2);
+  video_orc_unpack_UYVY (d, s, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
     d[i * 4 + 0] = 0xff;
-    d[i * 4 + 1] = line[i * 2 + 1];
-    d[i * 4 + 2] = line[i * 2 + 0];
-    d[i * 4 + 3] = line[i * 2 + 2];
+    d[i * 4 + 1] = s[i * 2 + 1];
+    d[i * 4 + 2] = s[i * 2 + 0];
+    d[i * 4 + 3] = s[i * 2 + 2];
   }
 }
 
@@ -190,19 +224,19 @@ pack_UYVY (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  guint8 *line = GET_LINE (y);
-  const guint8 *ayuv = src;
+  guint8 *d = GET_LINE (y);
+  const guint8 *s = src;
 
-  g_return_if_fail (IS_ALIGNED (src, 8));
+  g_return_if_fail (IS_ALIGNED (s, 8));
 
-  video_orc_pack_UYVY (line, src, width / 2);
+  video_orc_pack_UYVY (d, s, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
-    line[i * 2 + 0] = ayuv[i * 4 + 2];
-    line[i * 2 + 1] = ayuv[i * 4 + 1];
-    line[i * 2 + 2] = ayuv[i * 4 + 3];
+    d[i * 2 + 0] = s[i * 4 + 2];
+    d[i * 2 + 1] = s[i * 4 + 1];
+    d[i * 2 + 2] = s[i * 4 + 3];
   }
 }
 
@@ -212,20 +246,31 @@ unpack_YVYU (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  guint8 *line = GET_LINE (y);
+  const guint8 *s = GET_LINE (y);
   guint8 *d = dest;
 
-  g_return_if_fail (IS_ALIGNED (dest, 8));
+  s += (x & ~1) << 1;
+  if (x & 1) {
+    d[0] = 0xff;
+    d[1] = s[2];
+    d[2] = s[3];
+    d[3] = s[1];
+    s += 4;
+    d += 4;
+    width--;
+  }
+
+  g_return_if_fail (IS_ALIGNED (d, 8));
 
-  video_orc_unpack_YVYU (dest, line, width / 2);
+  video_orc_unpack_YVYU (d, s, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
     d[i * 4 + 0] = 0xff;
-    d[i * 4 + 1] = line[i * 2 + 0];
-    d[i * 4 + 2] = line[i * 2 + 3];
-    d[i * 4 + 3] = line[i * 2 + 1];
+    d[i * 4 + 1] = s[i * 2 + 0];
+    d[i * 4 + 2] = s[i * 2 + 3];
+    d[i * 4 + 3] = s[i * 2 + 1];
   }
 }
 
@@ -235,19 +280,19 @@ pack_YVYU (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  guint8 *line = GET_LINE (y);
-  const guint8 *ayuv = src;
+  guint8 *d = GET_LINE (y);
+  const guint8 *s = src;
 
-  g_return_if_fail (IS_ALIGNED (src, 8));
+  g_return_if_fail (IS_ALIGNED (s, 8));
 
-  video_orc_pack_YVYU (line, src, width / 2);
+  video_orc_pack_YVYU (d, s, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
-    line[i * 2 + 0] = ayuv[i * 4 + 1];
-    line[i * 2 + 1] = ayuv[i * 4 + 3];
-    line[i * 2 + 3] = ayuv[i * 4 + 2];
+    d[i * 2 + 0] = s[i * 4 + 1];
+    d[i * 2 + 1] = s[i * 4 + 3];
+    d[i * 2 + 3] = s[i * 4 + 2];
   }
 }
 
@@ -261,6 +306,8 @@ unpack_v308 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint8 *s = GET_LINE (y);
   guint8 *d = dest;
 
+  s += x * 3;
+
   for (i = 0; i < width; i++) {
     d[i * 4 + 0] = 0xff;
     d[i * 4 + 1] = s[i * 3 + 0];
@@ -293,7 +340,11 @@ unpack_copy4 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  memcpy (dest, GET_LINE (y), width * 4);
+  const guint8 *s = GET_LINE (y);
+
+  s += x * 4;
+
+  memcpy (dest, s, width * 4);
 }
 
 static void
@@ -302,7 +353,9 @@ pack_copy4 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  memcpy (GET_LINE (y), src, width * 4);
+  guint8 *d = GET_LINE (y);
+
+  memcpy (d, src, width * 4);
 }
 
 #define PACK_v210 GST_VIDEO_FORMAT_AYUV64, unpack_v210, 1, pack_v210
@@ -319,6 +372,9 @@ unpack_v210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   guint16 u0, u2, u4;
   guint16 v0, v2, v4;
 
+  /* FIXME */
+  s += x * 2;
+
   for (i = 0; i < width; i += 6) {
     a0 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 0);
     a1 = GST_READ_UINT32_LE (s + (i / 6) * 16 + 4);
@@ -489,6 +545,17 @@ unpack_v216 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint8 *s = GET_LINE (y);
   guint16 *d = dest;
 
+  s += (x & ~1) << 2;
+  if (x & 1) {
+    d[0] = 0xffff;
+    d[1] = GST_READ_UINT16_LE (s + 6);
+    d[2] = GST_READ_UINT16_LE (s + 0);
+    d[3] = GST_READ_UINT16_LE (s + 4);
+    s += 8;
+    d += 4;
+    width--;
+  }
+
   for (i = 0; i < width; i++) {
     d[i * 4 + 0] = 0xffff;
     d[i * 4 + 1] = GST_READ_UINT16_LE (s + i * 4 + 2);
@@ -527,22 +594,39 @@ unpack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  guint8 *y_line = GET_Y_LINE (y);
-  guint8 *u_line = GET_U_LINE (y);
-  guint8 *v_line = GET_V_LINE (y);
+  const guint8 *sy = GET_Y_LINE (y);
+  const guint8 *su = GET_U_LINE (y);
+  const guint8 *sv = GET_V_LINE (y);
   guint8 *d = dest;
 
-  g_return_if_fail (IS_ALIGNED (dest, 8));
+  sy += x;
+  su += x >> 2;
+  sv += x >> 2;
+
+  if (x & 3) {
+    for (; x & 3; x++) {
+      d[0] = 0xff;
+      d[1] = *sy++;
+      d[2] = *su;
+      d[3] = *sv;
+      width--;
+      d += 4;
+    }
+    su++;
+    sy++;
+  }
+
+  g_return_if_fail (IS_ALIGNED (d, 8));
 
-  video_orc_unpack_YUV9 (dest, y_line, u_line, v_line, width / 2);
+  video_orc_unpack_YUV9 (d, sy, su, sv, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
     d[i * 4 + 0] = 0xff;
-    d[i * 4 + 1] = y_line[i];
-    d[i * 4 + 2] = u_line[i >> 2];
-    d[i * 4 + 3] = v_line[i >> 2];
+    d[i * 4 + 1] = sy[i];
+    d[i * 4 + 2] = su[i >> 2];
+    d[i * 4 + 3] = sv[i >> 2];
   }
 }
 
@@ -553,28 +637,28 @@ pack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   int i;
-  guint8 *destY = GET_Y_LINE (y);
-  guint8 *destU = GET_U_LINE (y);
-  guint8 *destV = GET_V_LINE (y);
+  guint8 *dy = GET_Y_LINE (y);
+  guint8 *du = GET_U_LINE (y);
+  guint8 *dv = GET_V_LINE (y);
   const guint8 *s = src;
 
   for (i = 0; i < width - 3; i += 4) {
-    destY[i] = s[i * 4 + 1];
-    destY[i + 1] = s[i * 4 + 5];
-    destY[i + 2] = s[i * 4 + 9];
-    destY[i + 3] = s[i * 4 + 13];
+    dy[i] = s[i * 4 + 1];
+    dy[i + 1] = s[i * 4 + 5];
+    dy[i + 2] = s[i * 4 + 9];
+    dy[i + 3] = s[i * 4 + 13];
 
-    destU[i >> 2] = s[i * 4 + 2];
-    destV[i >> 2] = s[i * 4 + 3];
+    du[i >> 2] = s[i * 4 + 2];
+    dv[i >> 2] = s[i * 4 + 3];
   }
   if (i < width) {
-    destY[i] = s[i * 4 + 1];
-    destU[i >> 2] = s[i * 4 + 2];
-    destV[i >> 2] = s[i * 4 + 3];
+    dy[i] = s[i * 4 + 1];
+    du[i >> 2] = s[i * 4 + 2];
+    dv[i >> 2] = s[i * 4 + 3];
     if (i < width - 1)
-      destY[i + 1] = s[i * 4 + 5];
+      dy[i + 1] = s[i * 4 + 5];
     if (i < width - 2)
-      destY[i + 2] = s[i * 4 + 9];
+      dy[i + 2] = s[i * 4 + 9];
   }
 }
 
@@ -584,22 +668,35 @@ unpack_Y42B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  guint8 *y_line = GET_Y_LINE (y);
-  guint8 *u_line = GET_U_LINE (y);
-  guint8 *v_line = GET_V_LINE (y);
+  const guint8 *sy = GET_Y_LINE (y);
+  const guint8 *su = GET_U_LINE (y);
+  const guint8 *sv = GET_V_LINE (y);
   guint8 *d = dest;
 
-  g_return_if_fail (IS_ALIGNED (dest, 8));
+  sy += x;
+  su += x >> 1;
+  sv += x >> 1;
+
+  if (x & 1) {
+    d[0] = 0xff;
+    d[1] = *sy++;
+    d[2] = *su++;
+    d[3] = *sv++;
+    width--;
+    d += 4;
+  }
+
+  g_return_if_fail (IS_ALIGNED (d, 8));
 
-  video_orc_unpack_Y42B (dest, y_line, u_line, v_line, width / 2);
+  video_orc_unpack_Y42B (d, sy, su, sv, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
     d[i * 4 + 0] = 0xff;
-    d[i * 4 + 1] = y_line[i];
-    d[i * 4 + 2] = u_line[i >> 1];
-    d[i * 4 + 3] = v_line[i >> 1];
+    d[i * 4 + 1] = sy[i];
+    d[i * 4 + 2] = su[i >> 1];
+    d[i * 4 + 3] = sv[i >> 1];
   }
 }
 
@@ -609,21 +706,21 @@ pack_Y42B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  guint8 *y_line = GET_Y_LINE (y);
-  guint8 *u_line = GET_U_LINE (y);
-  guint8 *v_line = GET_V_LINE (y);
-  const guint8 *ayuv = src;
+  guint8 *dy = GET_Y_LINE (y);
+  guint8 *du = GET_U_LINE (y);
+  guint8 *dv = GET_V_LINE (y);
+  const guint8 *s = src;
 
-  g_return_if_fail (IS_ALIGNED (src, 8));
+  g_return_if_fail (IS_ALIGNED (s, 8));
 
-  video_orc_pack_Y42B (y_line, u_line, v_line, src, width / 2);
+  video_orc_pack_Y42B (dy, du, dv, s, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
-    y_line[i] = ayuv[i * 4 + 1];
-    u_line[i >> 1] = ayuv[i * 4 + 2];
-    v_line[i >> 1] = ayuv[i * 4 + 3];
+    dy[i] = s[i * 4 + 1];
+    du[i >> 1] = s[i * 4 + 2];
+    dv[i >> 1] = s[i * 4 + 3];
   }
 }
 
@@ -633,8 +730,15 @@ unpack_Y444 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  video_orc_unpack_Y444 (dest, GET_Y_LINE (y), GET_U_LINE (y),
-      GET_V_LINE (y), width);
+  const guint8 *sy = GET_Y_LINE (y);
+  const guint8 *su = GET_U_LINE (y);
+  const guint8 *sv = GET_V_LINE (y);
+
+  sy += x;
+  su += x;
+  sv += x;
+
+  video_orc_unpack_Y444 (dest, sy, su, sv, width);
 }
 
 static void
@@ -643,8 +747,11 @@ pack_Y444 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  video_orc_pack_Y444 (GET_Y_LINE (y), GET_U_LINE (y), GET_V_LINE (y), src,
-      width);
+  guint8 *dy = GET_Y_LINE (y);
+  guint8 *du = GET_U_LINE (y);
+  guint8 *dv = GET_V_LINE (y);
+
+  video_orc_pack_Y444 (dy, du, dv, src, width);
 }
 
 #define PACK_GBR GST_VIDEO_FORMAT_ARGB, unpack_GBR, 1, pack_GBR
@@ -653,8 +760,15 @@ unpack_GBR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  video_orc_unpack_Y444 (dest, GET_R_LINE (y), GET_G_LINE (y),
-      GET_B_LINE (y), width);
+  const guint8 *sr = GET_R_LINE (y);
+  const guint8 *sg = GET_G_LINE (y);
+  const guint8 *sb = GET_B_LINE (y);
+
+  sr += x * 4;
+  sg += x * 4;
+  sb += x * 4;
+
+  video_orc_unpack_Y444 (dest, sr, sg, sb, width);
 }
 
 static void
@@ -663,8 +777,11 @@ pack_GBR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  video_orc_pack_Y444 (GET_R_LINE (y), GET_G_LINE (y), GET_B_LINE (y), src,
-      width);
+  guint8 *dr = GET_R_LINE (y);
+  guint8 *dg = GET_G_LINE (y);
+  guint8 *db = GET_B_LINE (y);
+
+  video_orc_pack_Y444 (dr, dg, db, src, width);
 }
 
 #define PACK_GRAY8 GST_VIDEO_FORMAT_AYUV, unpack_GRAY8, 1, pack_GRAY8
@@ -673,7 +790,11 @@ unpack_GRAY8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  video_orc_unpack_GRAY8 (dest, GET_LINE (y), width);
+  const guint8 *s = GET_LINE (y);
+
+  s += x;
+
+  video_orc_unpack_GRAY8 (dest, s, width);
 }
 
 static void
@@ -682,7 +803,9 @@ pack_GRAY8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  video_orc_pack_GRAY8 (GET_LINE (y), src, width);
+  guint8 *d = GET_LINE (y);
+
+  video_orc_pack_GRAY8 (d, src, width);
 }
 
 #define PACK_GRAY16_BE GST_VIDEO_FORMAT_AYUV64, unpack_GRAY16_BE, 1, pack_GRAY16_BE
@@ -695,6 +818,8 @@ unpack_GRAY16_BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint16 *s = GET_LINE (y);
   guint16 *d = dest;
 
+  s += x;
+
   for (i = 0; i < width; i++) {
     d[i * 4 + 0] = 0xffff;
     d[i * 4 + 1] = GST_READ_UINT16_BE (s + i);
@@ -728,6 +853,8 @@ unpack_GRAY16_LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint16 *s = GET_LINE (y);
   guint16 *d = dest;
 
+  s += x;
+
   for (i = 0; i < width; i++) {
     d[i * 4 + 0] = 0xffff;
     d[i * 4 + 1] = GST_READ_UINT16_LE (s + i);
@@ -761,6 +888,8 @@ unpack_RGB16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint16 *s = GET_LINE (y);
   guint8 *d = dest, r, g, b;
 
+  s += x;
+
   for (i = 0; i < width; i++) {
     r = ((s[i] >> 11) & 0x1f) << 3;
     g = ((s[i] >> 5) & 0x3f) << 2;
@@ -805,6 +934,8 @@ unpack_BGR16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint16 *s = GET_LINE (y);
   guint8 *d = dest, r, g, b;
 
+  s += x;
+
   for (i = 0; i < width; i++) {
     b = ((s[i] >> 11) & 0x1f) << 3;
     g = ((s[i] >> 5) & 0x3f) << 2;
@@ -849,6 +980,8 @@ unpack_RGB15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint16 *s = GET_LINE (y);
   guint8 *d = dest, r, g, b;
 
+  s += x;
+
   for (i = 0; i < width; i++) {
     r = ((s[i] >> 10) & 0x1f) << 3;
     g = ((s[i] >> 5) & 0x1f) << 3;
@@ -893,6 +1026,8 @@ unpack_BGR15 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint16 *s = GET_LINE (y);
   guint8 *d = dest, r, g, b;
 
+  s += x;
+
   for (i = 0; i < width; i++) {
     b = ((s[i] >> 10) & 0x1f) << 3;
     g = ((s[i] >> 5) & 0x1f) << 3;
@@ -933,7 +1068,11 @@ unpack_BGRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  video_orc_unpack_BGRA (dest, GET_LINE (y), width);
+  const guint8 *s = GET_LINE (y);
+
+  s += x * 4;
+
+  video_orc_unpack_BGRA (dest, s, width);
 }
 
 static void
@@ -942,7 +1081,9 @@ pack_BGRA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  video_orc_pack_BGRA (GET_LINE (y), src, width);
+  guint8 *d = GET_LINE (y);
+
+  video_orc_pack_BGRA (d, src, width);
 }
 
 #define PACK_ABGR GST_VIDEO_FORMAT_ARGB, unpack_ABGR, 1, pack_ABGR
@@ -951,7 +1092,11 @@ unpack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  video_orc_unpack_ABGR (dest, GET_LINE (y), width);
+  const guint8 *s = GET_LINE (y);
+
+  s += x * 4;
+
+  video_orc_unpack_ABGR (dest, s, width);
 }
 
 static void
@@ -960,7 +1105,9 @@ pack_ABGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  video_orc_pack_ABGR (GET_LINE (y), src, width);
+  guint8 *d = GET_LINE (y);
+
+  video_orc_pack_ABGR (d, src, width);
 }
 
 #define PACK_RGBA GST_VIDEO_FORMAT_ARGB, unpack_RGBA, 1, pack_RGBA
@@ -969,7 +1116,11 @@ unpack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  video_orc_unpack_RGBA (dest, GET_LINE (y), width);
+  const guint8 *s = GET_LINE (y);
+
+  s += x * 4;
+
+  video_orc_unpack_RGBA (dest, s, width);
 }
 
 static void
@@ -978,7 +1129,9 @@ pack_RGBA (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  video_orc_pack_RGBA (GET_LINE (y), src, width);
+  guint8 *d = GET_LINE (y);
+
+  video_orc_pack_RGBA (d, src, width);
 }
 
 #define PACK_RGB GST_VIDEO_FORMAT_ARGB, unpack_RGB, 1, pack_RGB
@@ -991,6 +1144,8 @@ unpack_RGB (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint8 *s = GET_LINE (y);
   guint8 *d = dest;
 
+  s += x * 3;
+
   for (i = 0; i < width; i++) {
     d[i * 4 + 0] = 0xff;
     d[i * 4 + 1] = s[i * 3 + 0];
@@ -1026,6 +1181,8 @@ unpack_BGR (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint8 *s = GET_LINE (y);
   guint8 *d = dest;
 
+  s += x * 3;
+
   for (i = 0; i < width; i++) {
     d[i * 4 + 0] = 0xff;
     d[i * 4 + 1] = s[i * 3 + 2];
@@ -1058,21 +1215,34 @@ unpack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   gint uv = GET_UV_420 (y, flags);
-  guint8 *y_line = GET_PLANE_LINE (0, y);
-  guint8 *uv_line = GET_PLANE_LINE (1, uv);
+  const guint8 *sy = GET_PLANE_LINE (0, y);
+  const guint8 *suv = GET_PLANE_LINE (1, uv);
   guint8 *d = dest;
 
-  g_return_if_fail (IS_ALIGNED (dest, 8));
+  sy += x;
+  suv += (x & ~1);
 
-  video_orc_unpack_NV12 (dest, y_line, uv_line, width / 2);
+  if (x & 1) {
+    d[0] = 0xff;
+    d[1] = *sy++;
+    d[2] = suv[0];
+    d[3] = suv[1];
+    width--;
+    d += 4;
+    suv += 2;
+  }
+
+  g_return_if_fail (IS_ALIGNED (d, 8));
+
+  video_orc_unpack_NV12 (d, sy, suv, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
     d[i * 4 + 0] = 0xff;
-    d[i * 4 + 1] = y_line[i];
-    d[i * 4 + 2] = uv_line[i + 0];
-    d[i * 4 + 3] = uv_line[i + 1];
+    d[i * 4 + 1] = sy[i];
+    d[i * 4 + 2] = suv[i + 0];
+    d[i * 4 + 3] = suv[i + 1];
   }
 }
 
@@ -1083,24 +1253,24 @@ pack_NV12 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   gint uv = GET_UV_420 (y, flags);
-  guint8 *y_line = GET_PLANE_LINE (0, y);
-  guint8 *uv_line = GET_PLANE_LINE (1, uv);
-  const guint8 *ayuv = src;
+  guint8 *dy = GET_PLANE_LINE (0, y);
+  guint8 *duv = GET_PLANE_LINE (1, uv);
+  const guint8 *s = src;
 
   if (IS_CHROMA_LINE_420 (y, flags)) {
-    g_return_if_fail (IS_ALIGNED (src, 8));
+    g_return_if_fail (IS_ALIGNED (s, 8));
 
-    video_orc_pack_NV12 (y_line, uv_line, src, width / 2);
+    video_orc_pack_NV12 (dy, duv, s, width / 2);
 
     if (width & 1) {
       gint i = width - 1;
 
-      y_line[i] = ayuv[i * 4 + 1];
-      uv_line[i + 0] = ayuv[i * 4 + 2];
-      uv_line[i + 1] = ayuv[i * 4 + 3];
+      dy[i] = s[i * 4 + 1];
+      duv[i + 0] = s[i * 4 + 2];
+      duv[i + 1] = s[i * 4 + 3];
     }
   } else
-    video_orc_pack_Y (y_line, src, width);
+    video_orc_pack_Y (dy, s, width);
 }
 
 #define PACK_NV21 GST_VIDEO_FORMAT_AYUV, unpack_NV21, 1, pack_NV21
@@ -1110,21 +1280,34 @@ unpack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   gint uv = GET_UV_420 (y, flags);
-  guint8 *y_line = GET_PLANE_LINE (0, y);
-  guint8 *uv_line = GET_PLANE_LINE (1, uv);
+  const guint8 *sy = GET_PLANE_LINE (0, y);
+  const guint8 *suv = GET_PLANE_LINE (1, uv);
   guint8 *d = dest;
 
-  g_return_if_fail (IS_ALIGNED (dest, 8));
+  sy += x;
+  suv += (x & ~1);
 
-  video_orc_unpack_NV21 (dest, y_line, uv_line, width / 2);
+  if (x & 1) {
+    d[0] = 0xff;
+    d[1] = *sy++;
+    d[2] = suv[1];
+    d[3] = suv[0];
+    width--;
+    d += 4;
+    suv += 2;
+  }
+
+  g_return_if_fail (IS_ALIGNED (d, 8));
+
+  video_orc_unpack_NV21 (d, sy, suv, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
     d[i * 4 + 0] = 0xff;
-    d[i * 4 + 1] = y_line[i];
-    d[i * 4 + 2] = uv_line[i + 1];
-    d[i * 4 + 3] = uv_line[i + 0];
+    d[i * 4 + 1] = sy[i];
+    d[i * 4 + 2] = suv[i + 1];
+    d[i * 4 + 3] = suv[i + 0];
   }
 }
 
@@ -1135,24 +1318,24 @@ pack_NV21 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   gint uv = GET_UV_420 (y, flags);
-  guint8 *y_line = GET_PLANE_LINE (0, y);
-  guint8 *uv_line = GET_PLANE_LINE (1, uv);
-  const guint8 *ayuv = src;
+  guint8 *dy = GET_PLANE_LINE (0, y);
+  guint8 *duv = GET_PLANE_LINE (1, uv);
+  const guint8 *s = src;
 
   if (IS_CHROMA_LINE_420 (y, flags)) {
-    g_return_if_fail (IS_ALIGNED (src, 8));
+    g_return_if_fail (IS_ALIGNED (s, 8));
 
-    video_orc_pack_NV21 (y_line, uv_line, src, width / 2);
+    video_orc_pack_NV21 (dy, duv, s, width / 2);
 
     if (width & 1) {
       gint i = width - 1;
 
-      y_line[i] = ayuv[i * 4 + 1];
-      uv_line[i + 0] = ayuv[i * 4 + 3];
-      uv_line[i + 1] = ayuv[i * 4 + 2];
+      dy[i] = s[i * 4 + 1];
+      duv[i + 0] = s[i * 4 + 3];
+      duv[i + 1] = s[i * 4 + 2];
     }
   } else
-    video_orc_pack_Y (y_line, src, width);
+    video_orc_pack_Y (dy, s, width);
 }
 
 #define PACK_NV16 GST_VIDEO_FORMAT_AYUV, unpack_NV16, 1, pack_NV16
@@ -1161,21 +1344,34 @@ unpack_NV16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  guint8 *y_line = GET_PLANE_LINE (0, y);
-  guint8 *uv_line = GET_PLANE_LINE (1, y);
+  const guint8 *sy = GET_PLANE_LINE (0, y);
+  const guint8 *suv = GET_PLANE_LINE (1, y);
   guint8 *d = dest;
 
-  g_return_if_fail (IS_ALIGNED (dest, 8));
+  sy += x;
+  suv += (x & ~1);
+
+  if (x & 1) {
+    d[0] = 0xff;
+    d[1] = *sy++;
+    d[2] = suv[0];
+    d[3] = suv[1];
+    width--;
+    d += 4;
+    suv += 2;
+  }
+
+  g_return_if_fail (IS_ALIGNED (d, 8));
 
-  video_orc_unpack_NV12 (dest, y_line, uv_line, width / 2);
+  video_orc_unpack_NV12 (d, sy, suv, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
     d[i * 4 + 0] = 0xff;
-    d[i * 4 + 1] = y_line[i];
-    d[i * 4 + 2] = uv_line[i + 0];
-    d[i * 4 + 3] = uv_line[i + 1];
+    d[i * 4 + 1] = sy[i];
+    d[i * 4 + 2] = suv[i + 0];
+    d[i * 4 + 3] = suv[i + 1];
   }
 }
 
@@ -1185,20 +1381,20 @@ pack_NV16 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  guint8 *y_line = GET_PLANE_LINE (0, y);
-  guint8 *uv_line = GET_PLANE_LINE (1, y);
-  const guint8 *ayuv = src;
+  guint8 *dy = GET_PLANE_LINE (0, y);
+  guint8 *duv = GET_PLANE_LINE (1, y);
+  const guint8 *s = src;
 
-  g_return_if_fail (IS_ALIGNED (src, 8));
+  g_return_if_fail (IS_ALIGNED (s, 8));
 
-  video_orc_pack_NV12 (y_line, uv_line, src, width / 2);
+  video_orc_pack_NV12 (dy, duv, s, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
-    y_line[i] = ayuv[i * 4 + 1];
-    uv_line[i + 0] = ayuv[i * 4 + 2];
-    uv_line[i + 1] = ayuv[i * 4 + 3];
+    dy[i] = s[i * 4 + 1];
+    duv[i + 0] = s[i * 4 + 2];
+    duv[i + 1] = s[i * 4 + 3];
   }
 }
 
@@ -1208,8 +1404,13 @@ unpack_NV24 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  video_orc_unpack_NV24 (dest,
-      GET_PLANE_LINE (0, y), GET_PLANE_LINE (1, y), width);
+  const guint8 *sy = GET_PLANE_LINE (0, y);
+  const guint8 *suv = GET_PLANE_LINE (1, y);
+
+  sy += x;
+  suv += x << 1;
+
+  video_orc_unpack_NV24 (dest, sy, suv, width);
 }
 
 static void
@@ -1218,8 +1419,10 @@ pack_NV24 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  video_orc_pack_NV24 (GET_PLANE_LINE (0, y),
-      GET_PLANE_LINE (1, y), src, width);
+  guint8 *dy = GET_PLANE_LINE (0, y);
+  guint8 *duv = GET_PLANE_LINE (1, y);
+
+  video_orc_pack_NV24 (dy, duv, src, width);
 }
 
 #define PACK_UYVP GST_VIDEO_FORMAT_AYUV64, unpack_UYVP, 1, pack_UYVP
@@ -1232,6 +1435,9 @@ unpack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint8 *s = GET_LINE (y);
   guint16 *d = dest;
 
+  /* FIXME */
+  s += x << 1;
+
   for (i = 0; i < width; i += 2) {
     guint16 y0, y1;
     guint16 u0;
@@ -1302,9 +1508,26 @@ unpack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   gint uv = GET_UV_420 (y, flags);
+  const guint8 *sy = GET_Y_LINE (y);
+  const guint8 *su = GET_U_LINE (uv);
+  const guint8 *sv = GET_V_LINE (uv);
+  const guint8 *sa = GET_A_LINE (y);
+  guint8 *d = dest;
+
+  sy += x;
+  su += x >> 1;
+  sv += x >> 1;
+  sa += x;
 
-  video_orc_unpack_A420 (dest, GET_Y_LINE (y), GET_U_LINE (uv),
-      GET_V_LINE (uv), GET_A_LINE (y), width);
+  if (x & 1) {
+    d[0] = *sa++;
+    d[1] = *sy++;
+    d[2] = *su++;
+    d[3] = *sv++;
+    width--;
+    d += 4;
+  }
+  video_orc_unpack_A420 (d, sy, su, sv, sa, width);
 }
 
 static void
@@ -1314,27 +1537,27 @@ pack_A420 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   gint uv = GET_UV_420 (y, flags);
-  guint8 *y_line = GET_Y_LINE (y);
-  guint8 *u_line = GET_U_LINE (uv);
-  guint8 *v_line = GET_V_LINE (uv);
-  guint8 *a_line = GET_A_LINE (y);
-  const guint8 *ayuv = src;
+  guint8 *dy = GET_Y_LINE (y);
+  guint8 *du = GET_U_LINE (uv);
+  guint8 *dv = GET_V_LINE (uv);
+  guint8 *da = GET_A_LINE (y);
+  const guint8 *s = src;
 
   if (IS_CHROMA_LINE_420 (y, flags)) {
-    g_return_if_fail (IS_ALIGNED (src, 8));
+    g_return_if_fail (IS_ALIGNED (s, 8));
 
-    video_orc_pack_A420 (y_line, u_line, v_line, a_line, src, width / 2);
+    video_orc_pack_A420 (dy, du, dv, da, s, width / 2);
 
     if (width & 1) {
       gint i = width - 1;
 
-      a_line[i] = ayuv[i * 4 + 0];
-      y_line[i] = ayuv[i * 4 + 1];
-      u_line[i >> 1] = ayuv[i * 4 + 2];
-      v_line[i >> 1] = ayuv[i * 4 + 3];
+      da[i] = s[i * 4 + 0];
+      dy[i] = s[i * 4 + 1];
+      du[i >> 1] = s[i * 4 + 2];
+      dv[i >> 1] = s[i * 4 + 3];
     }
   } else
-    video_orc_pack_AY (y_line, a_line, src, width);
+    video_orc_pack_AY (dy, da, s, width);
 }
 
 #define PACK_RGB8P GST_VIDEO_FORMAT_ARGB, unpack_RGB8P, 1, pack_RGB8P
@@ -1348,6 +1571,8 @@ unpack_RGB8P (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint32 *p = data[1];
   guint8 *d = dest;
 
+  s += x;
+
   for (i = 0; i < width; i++) {
     guint32 v = p[s[i]];
     d[i * 4 + 0] = (v >> 24) & 0xff;
@@ -1432,22 +1657,39 @@ unpack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   gint uv = GET_UV_410 (y, flags);
-  guint8 *y_line = GET_Y_LINE (y);
-  guint8 *u_line = GET_U_LINE (uv);
-  guint8 *v_line = GET_V_LINE (uv);
+  const guint8 *sy = GET_Y_LINE (y);
+  const guint8 *su = GET_U_LINE (uv);
+  const guint8 *sv = GET_V_LINE (uv);
   guint8 *d = dest;
 
-  g_return_if_fail (IS_ALIGNED (dest, 8));
+  sy += x;
+  su += x >> 2;
+  sv += x >> 2;
+
+  if (x & 3) {
+    for (; x & 3; x++) {
+      d[0] = 0xff;
+      d[1] = *sy++;
+      d[2] = *su;
+      d[3] = *sv;
+      width--;
+      d += 4;
+    }
+    su++;
+    sy++;
+  }
+
+  g_return_if_fail (IS_ALIGNED (d, 8));
 
-  video_orc_unpack_YUV9 (dest, y_line, u_line, v_line, width / 2);
+  video_orc_unpack_YUV9 (d, sy, su, sv, width / 2);
 
   if (width & 1) {
     gint i = width - 1;
 
     d[i * 4 + 0] = 0xff;
-    d[i * 4 + 1] = y_line[i];
-    d[i * 4 + 2] = u_line[i >> 2];
-    d[i * 4 + 3] = v_line[i >> 2];
+    d[i * 4 + 1] = sy[i];
+    d[i * 4 + 2] = su[i >> 2];
+    d[i * 4 + 3] = sv[i >> 2];
   }
 }
 
@@ -1459,31 +1701,31 @@ pack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
 {
   int i;
   gint uv = GET_UV_410 (y, flags);
-  guint8 *destY = GET_Y_LINE (y);
-  guint8 *destU = GET_U_LINE (uv);
-  guint8 *destV = GET_V_LINE (uv);
+  guint8 *dy = GET_Y_LINE (y);
+  guint8 *du = GET_U_LINE (uv);
+  guint8 *dv = GET_V_LINE (uv);
   const guint8 *s = src;
 
   for (i = 0; i < width - 3; i += 4) {
-    destY[i] = s[i * 4 + 1];
-    destY[i + 1] = s[i * 4 + 5];
-    destY[i + 2] = s[i * 4 + 9];
-    destY[i + 3] = s[i * 4 + 13];
+    dy[i] = s[i * 4 + 1];
+    dy[i + 1] = s[i * 4 + 5];
+    dy[i + 2] = s[i * 4 + 9];
+    dy[i + 3] = s[i * 4 + 13];
     if (IS_CHROMA_LINE_410 (y, flags)) {
-      destU[i >> 2] = s[i * 4 + 2];
-      destV[i >> 2] = s[i * 4 + 3];
+      du[i >> 2] = s[i * 4 + 2];
+      dv[i >> 2] = s[i * 4 + 3];
     }
   }
   if (i < width) {
-    destY[i] = s[i * 4 + 1];
+    dy[i] = s[i * 4 + 1];
     if (IS_CHROMA_LINE_410 (y, flags)) {
-      destU[i >> 2] = s[i * 4 + 2];
-      destV[i >> 2] = s[i * 4 + 3];
+      du[i >> 2] = s[i * 4 + 2];
+      dv[i >> 2] = s[i * 4 + 3];
     }
     if (i < width - 1)
-      destY[i + 1] = s[i * 4 + 5];
+      dy[i + 1] = s[i * 4 + 5];
     if (i < width - 2)
-      destY[i + 2] = s[i * 4 + 9];
+      dy[i + 2] = s[i * 4 + 9];
   }
 }
 
@@ -1500,6 +1742,9 @@ unpack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   guint8 u0;
   guint8 v0;
 
+  /* FIXME */
+  s += x * 4;
+
   for (i = 0; i < width - 3; i += 4) {
     y0 = s[(i >> 2) * 6 + 1];
     y1 = s[(i >> 2) * 6 + 2];
@@ -1589,7 +1834,11 @@ unpack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
-  memcpy (dest, GET_LINE (y), width * 8);
+  const guint8 *s = GET_LINE (y);
+
+  s += x * 8;
+
+  memcpy (dest, s, width * 8);
 }
 
 static void
@@ -1598,7 +1847,9 @@ pack_copy8 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
     gint y, gint width)
 {
-  memcpy (GET_LINE (y), src, width * 8);
+  guint8 *d = GET_LINE (y);
+
+  memcpy (d, src, width * 8);
 }
 
 #define PACK_r210 GST_VIDEO_FORMAT_ARGB64, unpack_r210, 1, pack_r210
@@ -1611,6 +1862,8 @@ unpack_r210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
   const guint8 *s = GET_LINE (y);
   guint16 *d = dest, R, G, B;
 
+  s += x * 4;
+
   for (i = 0; i < width; i++) {
     guint32 x = GST_READ_UINT32_BE (s + i * 4);
 
@@ -1657,15 +1910,19 @@ unpack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   int i;
-  guint16 *srcG = GET_G_LINE (y);
-  guint16 *srcB = GET_B_LINE (y);
-  guint16 *srcR = GET_R_LINE (y);
+  const guint16 *sg = GET_G_LINE (y);
+  const guint16 *sb = GET_B_LINE (y);
+  const guint16 *sr = GET_R_LINE (y);
   guint16 *d = dest, G, B, R;
 
+  sg += x;
+  sb += x;
+  sr += x;
+
   for (i = 0; i < width; i++) {
-    G = GST_READ_UINT16_LE (srcG + i) << 6;
-    B = GST_READ_UINT16_LE (srcB + i) << 6;
-    R = GST_READ_UINT16_LE (srcR + i) << 6;
+    G = GST_READ_UINT16_LE (sg + i) << 6;
+    B = GST_READ_UINT16_LE (sb + i) << 6;
+    R = GST_READ_UINT16_LE (sr + i) << 6;
 
     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
       R |= (R >> 10);
@@ -1687,9 +1944,9 @@ pack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   int i;
-  guint16 *destG = GET_G_LINE (y);
-  guint16 *destB = GET_B_LINE (y);
-  guint16 *destR = GET_R_LINE (y);
+  guint16 *dg = GET_G_LINE (y);
+  guint16 *db = GET_B_LINE (y);
+  guint16 *dr = GET_R_LINE (y);
   guint16 G, B, R;
   const guint16 *s = src;
 
@@ -1698,9 +1955,9 @@ pack_GBR_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     B = (s[i * 4 + 3]) >> 6;
     R = (s[i * 4 + 1]) >> 6;
 
-    GST_WRITE_UINT16_LE (destG + i, G);
-    GST_WRITE_UINT16_LE (destB + i, B);
-    GST_WRITE_UINT16_LE (destR + i, R);
+    GST_WRITE_UINT16_LE (dg + i, G);
+    GST_WRITE_UINT16_LE (db + i, B);
+    GST_WRITE_UINT16_LE (dr + i, R);
   }
 }
 
@@ -1711,15 +1968,19 @@ unpack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   int i;
-  guint16 *srcG = GET_G_LINE (y);
-  guint16 *srcB = GET_B_LINE (y);
-  guint16 *srcR = GET_R_LINE (y);
+  const guint16 *sg = GET_G_LINE (y);
+  const guint16 *sb = GET_B_LINE (y);
+  const guint16 *sr = GET_R_LINE (y);
   guint16 *d = dest, G, B, R;
 
+  sg += x;
+  sb += x;
+  sr += x;
+
   for (i = 0; i < width; i++) {
-    G = GST_READ_UINT16_BE (srcG + i) << 6;
-    B = GST_READ_UINT16_BE (srcB + i) << 6;
-    R = GST_READ_UINT16_BE (srcR + i) << 6;
+    G = GST_READ_UINT16_BE (sg + i) << 6;
+    B = GST_READ_UINT16_BE (sb + i) << 6;
+    R = GST_READ_UINT16_BE (sr + i) << 6;
 
     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
       R |= (R >> 10);
@@ -1741,9 +2002,9 @@ pack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   int i;
-  guint16 *destG = GET_G_LINE (y);
-  guint16 *destB = GET_B_LINE (y);
-  guint16 *destR = GET_R_LINE (y);
+  guint16 *dg = GET_G_LINE (y);
+  guint16 *db = GET_B_LINE (y);
+  guint16 *dr = GET_R_LINE (y);
   guint16 G, B, R;
   const guint16 *s = src;
 
@@ -1752,9 +2013,9 @@ pack_GBR_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     B = s[i * 4 + 3] >> 6;
     R = s[i * 4 + 1] >> 6;
 
-    GST_WRITE_UINT16_BE (destG + i, G);
-    GST_WRITE_UINT16_BE (destB + i, B);
-    GST_WRITE_UINT16_BE (destR + i, R);
+    GST_WRITE_UINT16_BE (dg + i, G);
+    GST_WRITE_UINT16_BE (db + i, B);
+    GST_WRITE_UINT16_BE (dr + i, R);
   }
 }
 
@@ -1765,15 +2026,19 @@ unpack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   int i;
-  guint16 *srcY = GET_Y_LINE (y);
-  guint16 *srcU = GET_U_LINE (y);
-  guint16 *srcV = GET_V_LINE (y);
+  guint16 *sy = GET_Y_LINE (y);
+  guint16 *su = GET_U_LINE (y);
+  guint16 *sv = GET_V_LINE (y);
   guint16 *d = dest, Y, U, V;
 
+  sy += x;
+  su += x;
+  sv += x;
+
   for (i = 0; i < width; i++) {
-    Y = GST_READ_UINT16_LE (srcY + i) << 6;
-    U = GST_READ_UINT16_LE (srcU + i) << 6;
-    V = GST_READ_UINT16_LE (srcV + i) << 6;
+    Y = GST_READ_UINT16_LE (sy + i) << 6;
+    U = GST_READ_UINT16_LE (su + i) << 6;
+    V = GST_READ_UINT16_LE (sv + i) << 6;
 
     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
       Y |= (Y >> 10);
@@ -1795,9 +2060,9 @@ pack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   int i;
-  guint16 *destY = GET_Y_LINE (y);
-  guint16 *destU = GET_U_LINE (y);
-  guint16 *destV = GET_V_LINE (y);
+  guint16 *dy = GET_Y_LINE (y);
+  guint16 *du = GET_U_LINE (y);
+  guint16 *dv = GET_V_LINE (y);
   guint16 Y, U, V;
   const guint16 *s = src;
 
@@ -1806,9 +2071,9 @@ pack_Y444_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     U = (s[i * 4 + 2]) >> 6;
     V = (s[i * 4 + 3]) >> 6;
 
-    GST_WRITE_UINT16_LE (destY + i, Y);
-    GST_WRITE_UINT16_LE (destU + i, U);
-    GST_WRITE_UINT16_LE (destV + i, V);
+    GST_WRITE_UINT16_LE (dy + i, Y);
+    GST_WRITE_UINT16_LE (du + i, U);
+    GST_WRITE_UINT16_LE (dv + i, V);
   }
 }
 
@@ -1819,15 +2084,19 @@ unpack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   int i;
-  guint16 *srcY = GET_Y_LINE (y);
-  guint16 *srcU = GET_U_LINE (y);
-  guint16 *srcV = GET_V_LINE (y);
+  const guint16 *sy = GET_Y_LINE (y);
+  const guint16 *su = GET_U_LINE (y);
+  const guint16 *sv = GET_V_LINE (y);
   guint16 *d = dest, Y, U, V;
 
+  sy += x;
+  su += x;
+  sv += x;
+
   for (i = 0; i < width; i++) {
-    Y = GST_READ_UINT16_BE (srcY + i) << 6;
-    U = GST_READ_UINT16_BE (srcU + i) << 6;
-    V = GST_READ_UINT16_BE (srcV + i) << 6;
+    Y = GST_READ_UINT16_BE (sy + i) << 6;
+    U = GST_READ_UINT16_BE (su + i) << 6;
+    V = GST_READ_UINT16_BE (sv + i) << 6;
 
     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
       Y |= (Y >> 10);
@@ -1849,9 +2118,9 @@ pack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   int i;
-  guint16 *destY = GET_Y_LINE (y);
-  guint16 *destU = GET_U_LINE (y);
-  guint16 *destV = GET_V_LINE (y);
+  guint16 *dy = GET_Y_LINE (y);
+  guint16 *du = GET_U_LINE (y);
+  guint16 *dv = GET_V_LINE (y);
   guint16 Y, U, V;
   const guint16 *s = src;
 
@@ -1860,9 +2129,9 @@ pack_Y444_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     U = s[i * 4 + 2] >> 6;
     V = s[i * 4 + 3] >> 6;
 
-    GST_WRITE_UINT16_BE (destY + i, Y);
-    GST_WRITE_UINT16_BE (destU + i, U);
-    GST_WRITE_UINT16_BE (destV + i, V);
+    GST_WRITE_UINT16_BE (dy + i, Y);
+    GST_WRITE_UINT16_BE (du + i, U);
+    GST_WRITE_UINT16_BE (dv + i, V);
   }
 }
 
@@ -1874,15 +2143,19 @@ unpack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
 {
   int i;
   gint uv = GET_UV_420 (y, flags);
-  guint16 *srcY = GET_Y_LINE (y);
-  guint16 *srcU = GET_U_LINE (uv);
-  guint16 *srcV = GET_V_LINE (uv);
+  const guint16 *sy = GET_Y_LINE (y);
+  const guint16 *su = GET_U_LINE (uv);
+  const guint16 *sv = GET_V_LINE (uv);
   guint16 *d = dest, Y, U, V;
 
+  sy += x;
+  su += x >> 1;
+  sv += x >> 1;
+
   for (i = 0; i < width; i++) {
-    Y = GST_READ_UINT16_LE (srcY + i) << 6;
-    U = GST_READ_UINT16_LE (srcU + (i >> 1)) << 6;
-    V = GST_READ_UINT16_LE (srcV + (i >> 1)) << 6;
+    Y = GST_READ_UINT16_LE (sy + i) << 6;
+    U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
+    V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
 
     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
       Y |= (Y >> 10);
@@ -1894,6 +2167,12 @@ unpack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     d[i * 4 + 1] = Y;
     d[i * 4 + 2] = U;
     d[i * 4 + 3] = V;
+
+    if (x & 1) {
+      x = 0;
+      su++;
+      sv++;
+    }
   }
 }
 
@@ -1905,9 +2184,9 @@ pack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
 {
   int i;
   gint uv = GET_UV_420 (y, flags);
-  guint16 *destY = GET_Y_LINE (y);
-  guint16 *destU = GET_U_LINE (uv);
-  guint16 *destV = GET_V_LINE (uv);
+  guint16 *dy = GET_Y_LINE (y);
+  guint16 *du = GET_U_LINE (uv);
+  guint16 *dv = GET_V_LINE (uv);
   guint16 Y0, Y1, U, V;
   const guint16 *s = src;
 
@@ -1918,24 +2197,24 @@ pack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
       U = s[i * 4 + 2] >> 6;
       V = s[i * 4 + 3] >> 6;
 
-      GST_WRITE_UINT16_LE (destY + i + 0, Y0);
-      GST_WRITE_UINT16_LE (destY + i + 1, Y1);
-      GST_WRITE_UINT16_LE (destU + (i >> 1), U);
-      GST_WRITE_UINT16_LE (destV + (i >> 1), V);
+      GST_WRITE_UINT16_LE (dy + i + 0, Y0);
+      GST_WRITE_UINT16_LE (dy + i + 1, Y1);
+      GST_WRITE_UINT16_LE (du + (i >> 1), U);
+      GST_WRITE_UINT16_LE (dv + (i >> 1), V);
     }
     if (i == width - 1) {
       Y0 = s[i * 4 + 1] >> 6;
       U = s[i * 4 + 2] >> 6;
       V = s[i * 4 + 3] >> 6;
 
-      GST_WRITE_UINT16_LE (destY + i, Y0);
-      GST_WRITE_UINT16_LE (destU + (i >> 1), U);
-      GST_WRITE_UINT16_LE (destV + (i >> 1), V);
+      GST_WRITE_UINT16_LE (dy + i, Y0);
+      GST_WRITE_UINT16_LE (du + (i >> 1), U);
+      GST_WRITE_UINT16_LE (dv + (i >> 1), V);
     }
   } else {
     for (i = 0; i < width; i++) {
       Y0 = s[i * 4 + 1] >> 6;
-      GST_WRITE_UINT16_LE (destY + i, Y0);
+      GST_WRITE_UINT16_LE (dy + i, Y0);
     }
   }
 }
@@ -1948,15 +2227,19 @@ unpack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
 {
   int i;
   gint uv = GET_UV_420 (y, flags);
-  guint16 *srcY = GET_Y_LINE (y);
-  guint16 *srcU = GET_U_LINE (uv);
-  guint16 *srcV = GET_V_LINE (uv);
+  const guint16 *sy = GET_Y_LINE (y);
+  const guint16 *su = GET_U_LINE (uv);
+  const guint16 *sv = GET_V_LINE (uv);
   guint16 *d = dest, Y, U, V;
 
+  sy += x;
+  su += x >> 1;
+  sv += x >> 1;
+
   for (i = 0; i < width; i++) {
-    Y = GST_READ_UINT16_BE (srcY + i) << 6;
-    U = GST_READ_UINT16_BE (srcU + (i >> 1)) << 6;
-    V = GST_READ_UINT16_BE (srcV + (i >> 1)) << 6;
+    Y = GST_READ_UINT16_BE (sy + i) << 6;
+    U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
+    V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
 
     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
       Y |= (Y >> 10);
@@ -1968,6 +2251,12 @@ unpack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     d[i * 4 + 1] = Y;
     d[i * 4 + 2] = U;
     d[i * 4 + 3] = V;
+
+    if (x & 1) {
+      x = 0;
+      su++;
+      sv++;
+    }
   }
 }
 
@@ -1979,9 +2268,9 @@ pack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
 {
   int i;
   gint uv = GET_UV_420 (y, flags);
-  guint16 *destY = GET_Y_LINE (y);
-  guint16 *destU = GET_U_LINE (uv);
-  guint16 *destV = GET_V_LINE (uv);
+  guint16 *dy = GET_Y_LINE (y);
+  guint16 *du = GET_U_LINE (uv);
+  guint16 *dv = GET_V_LINE (uv);
   guint16 Y0, Y1, U, V;
   const guint16 *s = src;
 
@@ -1992,24 +2281,24 @@ pack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
       U = s[i * 4 + 2] >> 6;
       V = s[i * 4 + 3] >> 6;
 
-      GST_WRITE_UINT16_BE (destY + i + 0, Y0);
-      GST_WRITE_UINT16_BE (destY + i + 1, Y1);
-      GST_WRITE_UINT16_BE (destU + (i >> 1), U);
-      GST_WRITE_UINT16_BE (destV + (i >> 1), V);
+      GST_WRITE_UINT16_BE (dy + i + 0, Y0);
+      GST_WRITE_UINT16_BE (dy + i + 1, Y1);
+      GST_WRITE_UINT16_BE (du + (i >> 1), U);
+      GST_WRITE_UINT16_BE (dv + (i >> 1), V);
     }
     if (i == width - 1) {
       Y0 = s[i * 4 + 1] >> 6;
       U = s[i * 4 + 2] >> 6;
       V = s[i * 4 + 3] >> 6;
 
-      GST_WRITE_UINT16_BE (destY + i, Y0);
-      GST_WRITE_UINT16_BE (destU + (i >> 1), U);
-      GST_WRITE_UINT16_BE (destV + (i >> 1), V);
+      GST_WRITE_UINT16_BE (dy + i, Y0);
+      GST_WRITE_UINT16_BE (du + (i >> 1), U);
+      GST_WRITE_UINT16_BE (dv + (i >> 1), V);
     }
   } else {
     for (i = 0; i < width; i++) {
       Y0 = s[i * 4 + 1] >> 6;
-      GST_WRITE_UINT16_BE (destY + i, Y0);
+      GST_WRITE_UINT16_BE (dy + i, Y0);
     }
   }
 }
@@ -2021,15 +2310,19 @@ unpack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   int i;
-  guint16 *srcY = GET_Y_LINE (y);
-  guint16 *srcU = GET_U_LINE (y);
-  guint16 *srcV = GET_V_LINE (y);
+  const guint16 *sy = GET_Y_LINE (y);
+  const guint16 *su = GET_U_LINE (y);
+  const guint16 *sv = GET_V_LINE (y);
   guint16 *d = dest, Y, U, V;
 
+  sy += x;
+  su += x >> 1;
+  sv += x >> 1;
+
   for (i = 0; i < width; i++) {
-    Y = GST_READ_UINT16_LE (srcY + i) << 6;
-    U = GST_READ_UINT16_LE (srcU + (i >> 1)) << 6;
-    V = GST_READ_UINT16_LE (srcV + (i >> 1)) << 6;
+    Y = GST_READ_UINT16_LE (sy + i) << 6;
+    U = GST_READ_UINT16_LE (su + (i >> 1)) << 6;
+    V = GST_READ_UINT16_LE (sv + (i >> 1)) << 6;
 
     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
       Y |= (Y >> 10);
@@ -2041,6 +2334,12 @@ unpack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     d[i * 4 + 1] = Y;
     d[i * 4 + 2] = U;
     d[i * 4 + 3] = V;
+
+    if (x & 1) {
+      x = 0;
+      su++;
+      sv++;
+    }
   }
 }
 
@@ -2051,9 +2350,9 @@ pack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   int i;
-  guint16 *destY = GET_Y_LINE (y);
-  guint16 *destU = GET_U_LINE (y);
-  guint16 *destV = GET_V_LINE (y);
+  guint16 *dy = GET_Y_LINE (y);
+  guint16 *du = GET_U_LINE (y);
+  guint16 *dv = GET_V_LINE (y);
   guint16 Y0, Y1, U, V;
   const guint16 *s = src;
 
@@ -2063,19 +2362,19 @@ pack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     U = s[i * 4 + 2] >> 6;
     V = s[i * 4 + 3] >> 6;
 
-    GST_WRITE_UINT16_LE (destY + i + 0, Y0);
-    GST_WRITE_UINT16_LE (destY + i + 1, Y1);
-    GST_WRITE_UINT16_LE (destU + (i >> 1), U);
-    GST_WRITE_UINT16_LE (destV + (i >> 1), V);
+    GST_WRITE_UINT16_LE (dy + i + 0, Y0);
+    GST_WRITE_UINT16_LE (dy + i + 1, Y1);
+    GST_WRITE_UINT16_LE (du + (i >> 1), U);
+    GST_WRITE_UINT16_LE (dv + (i >> 1), V);
   }
   if (i == width - 1) {
     Y0 = s[i * 4 + 1] >> 6;
     U = s[i * 4 + 2] >> 6;
     V = s[i * 4 + 3] >> 6;
 
-    GST_WRITE_UINT16_LE (destY + i, Y0);
-    GST_WRITE_UINT16_LE (destU + (i >> 1), U);
-    GST_WRITE_UINT16_LE (destV + (i >> 1), V);
+    GST_WRITE_UINT16_LE (dy + i, Y0);
+    GST_WRITE_UINT16_LE (du + (i >> 1), U);
+    GST_WRITE_UINT16_LE (dv + (i >> 1), V);
   }
 }
 
@@ -2086,15 +2385,19 @@ unpack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
 {
   int i;
-  guint16 *srcY = GET_Y_LINE (y);
-  guint16 *srcU = GET_U_LINE (y);
-  guint16 *srcV = GET_V_LINE (y);
+  const guint16 *sy = GET_Y_LINE (y);
+  const guint16 *su = GET_U_LINE (y);
+  const guint16 *sv = GET_V_LINE (y);
   guint16 *d = dest, Y, U, V;
 
+  sy += x;
+  su += x >> 1;
+  sv += x >> 1;
+
   for (i = 0; i < width; i++) {
-    Y = GST_READ_UINT16_BE (srcY + i) << 6;
-    U = GST_READ_UINT16_BE (srcU + (i >> 1)) << 6;
-    V = GST_READ_UINT16_BE (srcV + (i >> 1)) << 6;
+    Y = GST_READ_UINT16_BE (sy + i) << 6;
+    U = GST_READ_UINT16_BE (su + (i >> 1)) << 6;
+    V = GST_READ_UINT16_BE (sv + (i >> 1)) << 6;
 
     if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
       Y |= (Y >> 10);
@@ -2106,6 +2409,12 @@ unpack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     d[i * 4 + 1] = Y;
     d[i * 4 + 2] = U;
     d[i * 4 + 3] = V;
+
+    if (x & 1) {
+      x = 0;
+      su++;
+      sv++;
+    }
   }
 }
 
@@ -2116,9 +2425,9 @@ pack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     gint y, gint width)
 {
   int i;
-  guint16 *destY = GET_Y_LINE (y);
-  guint16 *destU = GET_U_LINE (y);
-  guint16 *destV = GET_V_LINE (y);
+  guint16 *dy = GET_Y_LINE (y);
+  guint16 *du = GET_U_LINE (y);
+  guint16 *dv = GET_V_LINE (y);
   guint16 Y0, Y1, U, V;
   const guint16 *s = src;
 
@@ -2128,19 +2437,19 @@ pack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
     U = s[i * 4 + 2] >> 6;
     V = s[i * 4 + 3] >> 6;
 
-    GST_WRITE_UINT16_BE (destY + i + 0, Y0);
-    GST_WRITE_UINT16_BE (destY + i + 1, Y1);
-    GST_WRITE_UINT16_BE (destU + (i >> 1), U);
-    GST_WRITE_UINT16_BE (destV + (i >> 1), V);
+    GST_WRITE_UINT16_BE (dy + i + 0, Y0);
+    GST_WRITE_UINT16_BE (dy + i + 1, Y1);
+    GST_WRITE_UINT16_BE (du + (i >> 1), U);
+    GST_WRITE_UINT16_BE (dv + (i >> 1), V);
   }
   if (i == width - 1) {
     Y0 = s[i * 4 + 1] >> 6;
     U = s[i * 4 + 2] >> 6;
     V = s[i * 4 + 3] >> 6;
 
-    GST_WRITE_UINT16_BE (destY + i, Y0);
-    GST_WRITE_UINT16_BE (destU + (i >> 1), U);
-    GST_WRITE_UINT16_BE (destV + (i >> 1), V);
+    GST_WRITE_UINT16_BE (dy + i, Y0);
+    GST_WRITE_UINT16_BE (du + (i >> 1), U);
+    GST_WRITE_UINT16_BE (dv + (i >> 1), V);
   }
 }