Index: AVCodecDecoder.h
===================================================================
--- AVCodecDecoder.h	(revision 34009)
+++ AVCodecDecoder.h	(working copy)
@@ -14,6 +14,10 @@

 #include <MediaFormats.h>

+extern "C" {
+	#include "swscale.h"
+}
+
 #include "DecoderPlugin.h"
 #include "ReaderPlugin.h"

@@ -80,6 +84,7 @@
 			bool 				fCodecInitDone;

 			gfx_convert_func	fFormatConversionFunc;
+			SwsContext*			fSwsContext;

 			char*				fExtraData;
 			int					fExtraDataSize;
Index: gfx_util.h
===================================================================
--- gfx_util.h	(revision 34009)
+++ gfx_util.h	(working copy)
@@ -30,13 +30,14 @@
 // will become:
 typedef void (*gfx_convert_func) (AVFrame *in, AVFrame *out, int width, int height);

-// this function will try to find the best colorspaces for both the ff-codec and
+// this function will try to find the best colorspaces for both the ff-codec and
 // the Media Kit sides.
 gfx_convert_func resolve_colorspace(color_space cs, PixelFormat pixelFormat);

-const char *pixfmt_to_string(int p);
+const char *pixfmt_to_string(int format);

-color_space pixfmt_to_colorspace(int p);
+color_space pixfmt_to_colorspace(int format);
+PixelFormat colorspace_to_pixfmt(color_space format);

 void dump_ffframe(AVFrame *frame, const char *name);

Index: AVCodecDecoder.cpp
===================================================================
--- AVCodecDecoder.cpp	(revision 34009)
+++ AVCodecDecoder.cpp	(working copy)
@@ -73,6 +73,7 @@
 	fCodecInitDone(false),

 	fFormatConversionFunc(NULL),
+	fSwsContext(NULL),

 	fExtraData(NULL),
 	fExtraDataSize(0),
@@ -115,6 +116,9 @@
 	free(fInputPicture);
 	free(fContext);

+	if (fSwsContext != NULL)
+		sws_freeContext(fSwsContext);
+
 	delete[] fExtraData;
 	delete[] fOutputBuffer;
 }
@@ -453,7 +457,8 @@
 	// time using another pixel-format that is supported by the decoder.
 	// But libavcodec doesn't seem to offer any way to tell the decoder
 	// which format it should use.
-	fFormatConversionFunc = 0;
+//	fFormatConversionFunc = 0;
+	fSwsContext = NULL;
 	// Iterate over supported codec formats
 	for (int i = 0; i < 1; i++) {
 		// close any previous instance
@@ -465,11 +470,15 @@
 		if (avcodec_open(fContext, fCodec) >= 0) {
 			fCodecInitDone = true;

-			fFormatConversionFunc = resolve_colorspace(
-				fOutputVideoFormat.display.format, fContext->pix_fmt);
+//			fFormatConversionFunc = resolve_colorspace(
+//				fOutputVideoFormat.display.format, fContext->pix_fmt);
+			fSwsContext = sws_getContext(fContext->width, fContext->height,
+				fContext->pix_fmt, fContext->width, fContext->height,
+				colorspace_to_pixfmt(fOutputVideoFormat.display.format),
+				SWS_FAST_BILINEAR, NULL, NULL, NULL);
 		}
-		if (fFormatConversionFunc != NULL)
-			break;
+//		if (fFormatConversionFunc != NULL)
+//			break;
 	}

 	if (!fCodecInitDone) {
@@ -477,9 +486,13 @@
 		return B_ERROR;
 	}

-	if (fFormatConversionFunc == NULL) {
-		TRACE("no pixel format conversion function found or decoder has "
-			"not set the pixel format yet!\n");
+//	if (fFormatConversionFunc == NULL) {
+//		TRACE("no pixel format conversion function found or decoder has "
+//			"not set the pixel format yet!\n");
+//	}
+	if (fSwsContext == NULL) {
+		TRACE("No SWS Scale context or decoder has not set the pixel format "
+			"yet!\n");
 	}

 	if (fOutputVideoFormat.display.format == B_YCbCr422) {
@@ -707,15 +720,23 @@
 //				pixfmt_to_string(fContext->pix_fmt));

 			// Some decoders do not set pix_fmt until they have decoded 1 frame
-			if (fFormatConversionFunc == NULL) {
-				fFormatConversionFunc = resolve_colorspace(
-					fOutputVideoFormat.display.format, fContext->pix_fmt);
+//			if (fFormatConversionFunc == NULL) {
+//				fFormatConversionFunc = resolve_colorspace(
+//					fOutputVideoFormat.display.format, fContext->pix_fmt);
+//			}
+			if (fSwsContext == NULL) {
+				fSwsContext = sws_getContext(fContext->width, fContext->height,
+					fContext->pix_fmt, fContext->width, fContext->height,
+					colorspace_to_pixfmt(fOutputVideoFormat.display.format),
+					SWS_FAST_BILINEAR, NULL, NULL, NULL);
 			}
+
 			fOutputPicture->data[0] = (uint8_t*)outBuffer;
 			fOutputPicture->linesize[0]
 				= fOutputVideoFormat.display.bytes_per_row;

-			if (fFormatConversionFunc != NULL) {
+//			if (fFormatConversionFunc != NULL) {
+			if (fSwsContext != NULL) {
 				if (useDeinterlacedPicture) {
 					AVFrame inputFrame;
 					inputFrame.data[0] = deinterlacedPicture.data[0];
@@ -727,11 +748,18 @@
 					inputFrame.linesize[2] = deinterlacedPicture.linesize[2];
 					inputFrame.linesize[3] = deinterlacedPicture.linesize[3];

-					(*fFormatConversionFunc)(&inputFrame,
-						fOutputPicture, width, height);
+//					(*fFormatConversionFunc)(&inputFrame,
+//						fOutputPicture, width, height);
+					sws_scale(fSwsContext, inputFrame.data,
+						inputFrame.linesize, 0, fContext->height,
+						fOutputPicture->data, fOutputPicture->linesize);
 				} else {
-					(*fFormatConversionFunc)(fInputPicture, fOutputPicture,
-						width, height);
+//					(*fFormatConversionFunc)(fInputPicture, fOutputPicture,
+//						width, height);
+					// Run the pixel format conversion
+					sws_scale(fSwsContext, fInputPicture->data,
+						fInputPicture->linesize, 0, fContext->height,
+						fOutputPicture->data, fOutputPicture->linesize);
 				}
 			}
 			if (fInputPicture->interlaced_frame)
Index: gfx_util.cpp
===================================================================
--- gfx_util.cpp	(revision 34009)
+++ gfx_util.cpp	(working copy)
@@ -16,7 +16,7 @@
   #define TRACE(a...)
 #endif

-// this function will try to find the best colorspaces for both the ff-codec and
+// this function will try to find the best colorspaces for both the ff-codec and
 // the Media Kit sides.
 gfx_convert_func resolve_colorspace(color_space colorSpace, PixelFormat pixelFormat)
 {
@@ -34,7 +34,7 @@
 					return gfx_conv_yuv410p_rgb32_c;
 //				}
 			}
-
+
 			if (pixelFormat == PIX_FMT_YUV411P) {
 //				if (cpu.HasMMX()) {
 //					TRACE("resolve_colorspace: gfx_conv_yuv411p_rgb32_mmx\n");
@@ -44,7 +44,7 @@
 					return gfx_conv_yuv411p_rgb32_c;
 //				}
 			}
-
+
 			if (pixelFormat == PIX_FMT_YUV420P || pixelFormat == PIX_FMT_YUVJ420P) {
 				if (cpu.HasSSE2()) {
 					TRACE("resolve_colorspace: gfx_conv_yuv420p_rgba32_sse2\n");
@@ -54,7 +54,7 @@
 					return gfx_conv_YCbCr420p_RGB32_c;
 				}
 			}
-
+
 			if (pixelFormat == PIX_FMT_YUV422P || pixelFormat == PIX_FMT_YUVJ422P) {
 				if (cpu.HasSSE2()) {
 					return gfx_conv_yuv422p_rgba32_sse2;
@@ -95,7 +95,7 @@
 					return gfx_conv_yuv411p_ycbcr422_c;
 //				}
 			}
-
+
 			if (pixelFormat == PIX_FMT_YUV420P || pixelFormat == PIX_FMT_YUVJ420P) {
 //				if (cpu.HasMMX()) {
 //					TRACE("resolve_colorspace: gfx_conv_yuv420p_ycbcr422_mmx\n");
@@ -105,7 +105,7 @@
 					return gfx_conv_yuv420p_ycbcr422_c;
 //				}
 			}
-
+
 			if (pixelFormat == PIX_FMT_YUYV422) {
 //				if (cpu.HasMMX()) {
 //					TRACE("resolve_colorspace: PIX_FMT_YUV422 => B_YCbCr422: gfx_conv_null_mmx\n");
@@ -115,10 +115,10 @@
 					return gfx_conv_null_c;
 //				}
 			}
-
+
 			TRACE("resolve_colorspace: %s => B_YCbCr422: NULL\n", pixfmt_to_string(pixelFormat));
 			return gfx_conv_null_c;
-
+
 		default:
 			TRACE("resolve_colorspace: default: NULL !!!\n");
 			return NULL;
@@ -248,19 +248,67 @@
 }


+PixelFormat
+colorspace_to_pixfmt(color_space format)
+{
+	switch(format) {
+		default:
+		case B_NO_COLOR_SPACE:
+			return PIX_FMT_NONE;
+
+		// NOTE: See pixfmt_to_colorspace() for what these are.
+		case B_YUV420:
+			return PIX_FMT_YUV420P;
+		case B_YUV422:
+			return PIX_FMT_YUV422P;
+		case B_RGB24_BIG:
+			return PIX_FMT_RGB24;
+		case B_RGB24:
+			return PIX_FMT_BGR24;
+		case B_YUV444:
+			return PIX_FMT_YUV444P;
+		case B_RGBA32_BIG:
+		case B_RGB32_BIG:
+			return PIX_FMT_BGR32;
+		case B_YUV9:
+			return PIX_FMT_YUV410P;
+		case B_YUV12:
+			return PIX_FMT_YUV411P;
+		// TODO: YCbCr color spaces! These are not the same as YUV!
+		case B_RGB16_BIG:
+			return PIX_FMT_RGB565;
+		case B_RGB15_BIG:
+			return PIX_FMT_RGB555;
+		case B_GRAY8:
+			return PIX_FMT_GRAY8;
+		case B_GRAY1:
+			return PIX_FMT_MONOBLACK;
+		case B_CMAP8:
+			return PIX_FMT_PAL8;
+		case B_RGBA32:
+		case B_RGB32:
+			return PIX_FMT_RGB32;
+		case B_RGB16:
+			return PIX_FMT_BGR565;
+		case B_RGB15:
+			return PIX_FMT_BGR555;
+	}
+}
+
+
 #define BEGIN_TAG "\033[31m"
 #define END_TAG "\033[0m"

 void dump_ffframe(AVFrame *frame, const char *name)
 {
 	const char *picttypes[] = {"no pict type", "intra", "predicted", "bidir pre", "s(gmc)-vop"};
-	printf(BEGIN_TAG"AVFrame(%s) pts:%-10lld cnum:%-5d dnum:%-5d %s%s, ]\n"END_TAG,
-		name,
-		frame->pts,
-		frame->coded_picture_number,
-		frame->display_picture_number,
-//		frame->quality,
-		frame->key_frame?"keyframe, ":"",
+	printf(BEGIN_TAG"AVFrame(%s) pts:%-10lld cnum:%-5d dnum:%-5d %s%s, ]\n"END_TAG,
+		name,
+		frame->pts,
+		frame->coded_picture_number,
+		frame->display_picture_number,
+//		frame->quality,
+		frame->key_frame?"keyframe, ":"",
 		picttypes[frame->pict_type]);
 //	printf(BEGIN_TAG"\t\tlinesize[] = {%ld, %ld, %ld, %ld}\n"END_TAG, frame->linesize[0], frame->linesize[1], frame->linesize[2], frame->linesize[3]);
 }
