diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index f14b858ed655823e261811c62ddc10ba8291fb90..d2d7193d30589d296157e350ebb66e1cdfda038f 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -111,11 +111,13 @@ untested special converters
 			|| (x)==PIX_FMT_RGB32|| (x)==PIX_FMT_BGR24|| (x)==PIX_FMT_BGR565|| (x)==PIX_FMT_BGR555\
 			|| (x)==PIX_FMT_BGR32|| (x)==PIX_FMT_RGB24\
 			|| (x)==PIX_FMT_GRAY8 || (x)==PIX_FMT_YUV410P\
+			|| (x)==PIX_FMT_GRAY16BE || (x)==PIX_FMT_GRAY16LE\
 			|| (x)==PIX_FMT_YUV444P || (x)==PIX_FMT_YUV422P || (x)==PIX_FMT_YUV411P)
 #define isSupportedOut(x) ((x)==PIX_FMT_YUV420P || (x)==PIX_FMT_YUYV422 || (x)==PIX_FMT_UYVY422\
 			|| (x)==PIX_FMT_YUV444P || (x)==PIX_FMT_YUV422P || (x)==PIX_FMT_YUV411P\
 			|| isRGB(x) || isBGR(x)\
 			|| (x)==PIX_FMT_NV12 || (x)==PIX_FMT_NV21\
+			|| (x)==PIX_FMT_GRAY16BE || (x)==PIX_FMT_GRAY16LE\
 			|| (x)==PIX_FMT_GRAY8 || (x)==PIX_FMT_YUV410P)
 #define isPacked(x)    ((x)==PIX_FMT_YUYV422 || (x)==PIX_FMT_UYVY422 ||isRGB(x) || isBGR(x))
 
@@ -231,6 +233,10 @@ char *sws_format_name(enum PixelFormat format)
             return "rgb565";
         case PIX_FMT_RGB555:
             return "rgb555";
+        case PIX_FMT_GRAY16BE:
+            return "gray16be";
+        case PIX_FMT_GRAY16LE:
+            return "gray16le";
         case PIX_FMT_GRAY8:
             return "gray8";
         case PIX_FMT_MONOWHITE:
@@ -1726,6 +1732,72 @@ static int simpleCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSli
 	return srcSliceH;
 }
 
+static int gray16togray(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
+             int srcSliceH, uint8_t* dst[], int dstStride[]){
+
+	int length= c->srcW;
+	int y=      srcSliceY;
+	int height= srcSliceH;
+	int i, j;
+	uint8_t *srcPtr= src[0];
+	uint8_t *dstPtr= dst[0] + dstStride[0]*y;
+
+	if(!isGray(c->dstFormat)){
+		int height= -((-srcSliceH)>>c->chrDstVSubSample);
+		memset(dst[1], 128, dstStride[1]*height);
+		memset(dst[2], 128, dstStride[2]*height);
+	}
+	if(c->srcFormat == PIX_FMT_GRAY16LE) srcPtr++;
+	for(i=0; i<height; i++)
+	{
+		for(j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1];
+		srcPtr+= srcStride[0];
+		dstPtr+= dstStride[0];
+	}
+	return srcSliceH;
+}
+
+static int graytogray16(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
+             int srcSliceH, uint8_t* dst[], int dstStride[]){
+
+	int length= c->srcW;
+	int y=      srcSliceY;
+	int height= srcSliceH;
+	int i, j;
+	uint8_t *srcPtr= src[0];
+	uint8_t *dstPtr= dst[0] + dstStride[0]*y;
+	for(i=0; i<height; i++)
+	{
+		for(j=0; j<length; j++)
+		{
+			dstPtr[j<<1] = srcPtr[j];
+			dstPtr[(j<<1)+1] = srcPtr[j];
+		}
+		srcPtr+= srcStride[0];
+		dstPtr+= dstStride[0];
+	}
+	return srcSliceH;
+}
+
+static int gray16swap(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
+             int srcSliceH, uint8_t* dst[], int dstStride[]){
+
+	int length= c->srcW;
+	int y=      srcSliceY;
+	int height= srcSliceH;
+	int i, j;
+	uint16_t *srcPtr= src[0];
+	uint16_t *dstPtr= dst[0] + dstStride[0]*y/2;
+	for(i=0; i<height; i++)
+	{
+		for(j=0; j<length; j++) dstPtr[j] = bswap_16(srcPtr[j]);
+		srcPtr+= srcStride[0]/2;
+		dstPtr+= dstStride[0]/2;
+	}
+	return srcSliceH;
+}
+
+
 static void getSubSampleFactors(int *h, int *v, int format){
 	switch(format){
 	case PIX_FMT_UYVY422:
@@ -1734,6 +1806,8 @@ static void getSubSampleFactors(int *h, int *v, int format){
 		*v=0;
 		break;
 	case PIX_FMT_YUV420P:
+	case PIX_FMT_GRAY16BE:
+	case PIX_FMT_GRAY16LE:
 	case PIX_FMT_GRAY8: //FIXME remove after different subsamplings are fully implemented
 	case PIX_FMT_NV12:
 	case PIX_FMT_NV21:
@@ -2045,6 +2119,20 @@ SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, int dstW, int dstH
 			c->swScale= simpleCopy;
 		}
 
+		/* gray16{le,be} conversions */
+		if(isGray16(srcFormat) && (isPlanarYUV(dstFormat) || (dstFormat == PIX_FMT_GRAY8)))
+		{
+			c->swScale= gray16togray;
+		}
+		if((isPlanarYUV(srcFormat) || (srcFormat == PIX_FMT_GRAY8)) && isGray16(dstFormat))
+		{
+			c->swScale= graytogray16;
+		}
+		if(srcFormat != dstFormat && isGray16(srcFormat) && isGray16(dstFormat))
+		{
+			c->swScale= gray16swap;
+		}		
+
 		if(c->swScale){
 			if(flags&SWS_PRINT_INFO)
 				MSG_INFO("SwScaler: using unscaled %s -> %s special converter\n", 
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index ecd28f5ff47dd80df1426f453520b635101426c5..dbeee7d9784018889306e3c7619a16db119fbae7 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -181,7 +181,8 @@ char *sws_format_name(int format);
 			|| (x)==PIX_FMT_YUV444P || (x)==PIX_FMT_NV12	\
 			|| (x)==PIX_FMT_NV21)
 #define isYUV(x)       ((x)==PIX_FMT_UYVY422 || (x)==PIX_FMT_YUYV422 || isPlanarYUV(x))
-#define isGray(x)      ((x)==PIX_FMT_GRAY8)
+#define isGray(x)      ((x)==PIX_FMT_GRAY8 || (x)==PIX_FMT_GRAY16BE || (x)==PIX_FMT_GRAY16LE)
+#define isGray16(x)    ((x)==PIX_FMT_GRAY16BE || (x)==PIX_FMT_GRAY16LE)
 #define isRGB(x)       ((x)==PIX_FMT_BGR32 || (x)==PIX_FMT_RGB24	\
 			|| (x)==PIX_FMT_RGB565 || (x)==PIX_FMT_RGB555	\
 			|| (x)==PIX_FMT_RGB8 || (x)==PIX_FMT_RGB4	\
@@ -204,6 +205,8 @@ static inline int fmt_depth(int fmt)
             return 24;
         case PIX_FMT_BGR565:
         case PIX_FMT_RGB565:
+        case PIX_FMT_GRAY16BE:
+        case PIX_FMT_GRAY16LE:
             return 16;
         case PIX_FMT_BGR555:
         case PIX_FMT_RGB555:
diff --git a/libswscale/swscale_template.c b/libswscale/swscale_template.c
index cc8e87e37e7907b96fb258dac3d34bb1c08490ce..6b6b4bf65862fa87ce64eb0225e5ddab17a8ce35 100644
--- a/libswscale/swscale_template.c
+++ b/libswscale/swscale_template.c
@@ -2437,12 +2437,12 @@ static inline void RENAME(hyscale)(uint16_t *dst, long dstWidth, uint8_t *src, i
 				   int srcFormat, uint8_t *formatConvBuffer, int16_t *mmx2Filter,
 				   int32_t *mmx2FilterPos)
 {
-    if(srcFormat==PIX_FMT_YUYV422)
+    if(srcFormat==PIX_FMT_YUYV422 || srcFormat==PIX_FMT_GRAY16BE)
     {
 	RENAME(yuy2ToY)(formatConvBuffer, src, srcW);
 	src= formatConvBuffer;
     }
-    else if(srcFormat==PIX_FMT_UYVY422)
+    else if(srcFormat==PIX_FMT_UYVY422 || srcFormat==PIX_FMT_GRAY16LE)
     {
 	RENAME(uyvyToY)(formatConvBuffer, src, srcW);
 	src= formatConvBuffer;