Index: /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.cpp	(revision 41952)
+++ /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.cpp	(revision 41953)
@@ -76,4 +76,5 @@
  * it is called.
  */
+#ifdef VBOX_WITH_VPX
 FFmpegFB::FFmpegFB(ULONG width, ULONG height, ULONG bitrate,
                    com::Bstr filename) :
@@ -86,9 +87,44 @@
     mFrameWidth(width), mFrameHeight(height),
     mYUVFrameSize(width * height * 3 / 2),
-    mRGBBuffer(0), mpFormatContext(0), mpStream(0),
+    mRGBBuffer(0),
     mOutOfMemory(false), mToggle(false)
+#else
+FFmpegFB::FFmpegFB(ULONG width, ULONG height, ULONG bitrate,
+                   com::Bstr filename) :
+    mpFormatContext(0), mpStream(0),
+    mfUrlOpen(false),
+    mBitRate(bitrate),
+    mPixelFormat(FramebufferPixelFormat_Opaque),
+    mBitsPerPixel(0),
+    mFileName(filename),
+    mBytesPerLine(0),
+    mFrameWidth(width), mFrameHeight(height),
+    mYUVFrameSize(width * height * 3 / 2),mRGBBuffer(0),
+    mOutOfMemory(false), mToggle(false)
+#endif
 {
     ULONG cPixels = width * height;
 
+#ifdef VBOX_WITH_VPX
+    Assert(width % 2 == 0 && height % 2 == 0);
+    /* For temporary RGB frame we allocate enough memory to deal with
+       RGB16 to RGB32 */
+    mTempRGBBuffer = reinterpret_cast<uint8_t *>(malloc(cPixels * 4));
+    if (mTempRGBBuffer == 0)
+        goto nomem_temp_rgb_buffer;
+    mYUVBuffer = reinterpret_cast<uint8_t *>(malloc(mYUVFrameSize));
+    if (mYUVBuffer == 0)
+        goto nomem_yuv_buffer;
+    return;
+
+    /* C-based memory allocation and how to deal with it in C++ :) */
+nomem_yuv_buffer:
+    Log(("Failed to allocate memory for mYUVBuffer\n"));
+    free(mYUVBuffer);
+nomem_temp_rgb_buffer:
+    Log(("Failed to allocate memory for mTempRGBBuffer\n"));
+    free(mTempRGBBuffer);
+    mOutOfMemory = true;
+#else
     LogFlow(("Creating FFmpegFB object %p, width=%lu, height=%lu\n",
              this, (unsigned long) width,  (unsigned long) height));
@@ -124,4 +160,5 @@
     Log(("Failed to allocate memory for mTempRGBBuffer\n"));
     mOutOfMemory = true;
+#endif
 }
 
@@ -133,4 +170,30 @@
 {
     LogFlow(("Destroying FFmpegFB object %p\n", this));
+#ifdef VBOX_WITH_VPX
+	/* Dummy update to make sure we get all the frame (timing). */
+    NotifyUpdate(0, 0, 0, 0);
+    /* Write the last pending frame before exiting */
+    int rc = do_rgb_to_yuv_conversion();
+    if (rc == S_OK)
+		do_encoding_and_write();
+# if 1
+    /* Add another 10 seconds. */
+    for (int i = 10*25; i > 0; i--)
+		do_encoding_and_write();
+# endif
+    Ebml_WriteWebMFileFooter(&ebml, 0);
+	if(ebml.stream)
+	    fclose(ebml.stream);
+    vpx_codec_destroy(&mVpxCodec);
+    RTCritSectDelete(&mCritSect);
+
+	/* We have already freed the stream above */
+    if (mTempRGBBuffer != 0)
+        free(mTempRGBBuffer);
+    if (mYUVBuffer != 0)
+        free(mYUVBuffer);
+    if (mRGBBuffer != 0)
+        RTMemFree(mRGBBuffer);
+#else
     if (mpFormatContext != 0)
     {
@@ -143,9 +206,9 @@
             if (rc == S_OK)
                 do_encoding_and_write();
-#if 1
+# if 1
             /* Add another 10 seconds. */
             for (int i = 10*25; i > 0; i--)
                 do_encoding_and_write();
-#endif
+# endif
             /* write a png file of the last frame */
             write_png();
@@ -158,9 +221,9 @@
             }
 /* Changed sometime between 50.5.0 and 52.7.0 */
-#if LIBAVFORMAT_VERSION_INT >= (52 << 16)
+# if LIBAVFORMAT_VERSION_INT >= (52 << 16)
             url_fclose(mpFormatContext->pb);
-#else /* older version */
+# else /* older version */
             url_fclose(&mpFormatContext->pb);
-#endif /* older version */
+# endif /* older version */
         }
         av_free(mpFormatContext);
@@ -179,4 +242,5 @@
     if (mRGBBuffer != 0)
         RTMemFree(mRGBBuffer);
+#endif
 }
 
@@ -201,5 +265,20 @@
     if (mOutOfMemory == true)
         return E_OUTOFMEMORY;
-    int rc = RTCritSectInit(&mCritSect);
+	int rc;
+	int rcOpenFile;
+	int rcOpenCodec;
+
+#ifdef VBOX_WITH_VPX
+	mFrameCount = 0;
+    memset(&ebml, 0, sizeof(struct EbmlGlobal));
+    ebml.last_pts_ms = -1;
+    rc = RTCritSectInit(&mCritSect);
+    AssertReturn(rc == VINF_SUCCESS, E_UNEXPECTED);
+    rcOpenFile = open_output_file();
+    AssertReturn(rcOpenFile == S_OK, rcOpenFile);
+    rcOpenCodec = open_codec();
+    AssertReturn(rcOpenCodec == S_OK, rcOpenCodec);
+#else
+    rc = RTCritSectInit(&mCritSect);
     AssertReturn(rc == VINF_SUCCESS, E_UNEXPECTED);
     int rcSetupLibrary = setup_library();
@@ -207,12 +286,15 @@
     int rcSetupFormat = setup_output_format();
     AssertReturn(rcSetupFormat == S_OK, rcSetupFormat);
-    int rcOpenCodec = open_codec();
+    rcOpenCodec = open_codec();
     AssertReturn(rcOpenCodec == S_OK, rcOpenCodec);
-    int rcOpenFile = open_output_file();
+    rcOpenFile = open_output_file();
     AssertReturn(rcOpenFile == S_OK, rcOpenFile);
+
     /* Fill in the picture data for the AVFrame - not particularly
        elegant, but that is the API. */
     avpicture_fill((AVPicture *) mFrame, mYUVBuffer, PIX_FMT_YUV420P,
                    mFrameWidth, mFrameHeight);
+#endif
+
     /* Set the initial framebuffer size to the mpeg frame dimensions */
     BOOL finished;
@@ -536,4 +618,18 @@
         switch (bitsPerPixel)
         {
+#ifdef VBOX_WITH_VPX
+            case 32:
+                mFFMPEGPixelFormat = VPX_IMG_FMT_RGB32;
+                Log2(("FFmpeg::RequestResize: setting ffmpeg pixel format to VPX_IMG_FMT_RGB32\n"));
+                break;
+            case 24:
+                mFFMPEGPixelFormat = VPX_IMG_FMT_RGB24;
+                Log2(("FFmpeg::RequestResize: setting ffmpeg pixel format to VPX_IMG_FMT_RGB24\n"));
+                break;
+            case 16:
+                mFFMPEGPixelFormat = VPX_IMG_FMT_RGB565;
+                Log2(("FFmpeg::RequestResize: setting ffmpeg pixel format to VPX_IMG_FMT_RGB565\n"));
+                break;
+#else
             case 32:
                 mFFMPEGPixelFormat = PIX_FMT_RGBA32;
@@ -548,4 +644,5 @@
                 Log2(("FFmpeg::RequestResize: setting ffmpeg pixel format to PIX_FMT_RGB565\n"));
                 break;
+#endif
             default:
                 fallback = true;
@@ -572,6 +669,11 @@
         /* we always fallback to 32bpp RGB */
         mPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
+#ifdef VBOX_WITH_VPX
+        mFFMPEGPixelFormat = VPX_IMG_FMT_RGB32;
+        Log2(("FFmpeg::RequestResize: setting ffmpeg pixel format to VPX_IMG_FMT_RGB32\n"));
+#else
         mFFMPEGPixelFormat = PIX_FMT_RGBA32;
         Log2(("FFmpeg::RequestResize: setting ffmpeg pixel format to PIX_FMT_RGBA32\n"));
+#endif
 
         mBytesPerLine = w * 4;
@@ -637,5 +739,5 @@
 //////////////////////////////////////////////////////////////////////////
 //
-
+#ifndef VBOX_WITH_VPX
 HRESULT FFmpegFB::setup_library()
 {
@@ -669,5 +771,5 @@
     AVOutputFormat *pOutFormat = guess_format(0, com::Utf8Str(mFileName).c_str(),
                                               0);
-#ifdef VBOX_SHOW_AVAILABLE_FORMATS
+# ifdef VBOX_SHOW_AVAILABLE_FORMATS
     if (!pOutFormat)
     {
@@ -676,5 +778,5 @@
         list_formats();
     }
-#endif
+# endif
     AssertMsgReturn(pOutFormat != 0,
                     ("Could not deduce output format from file name\n"),
@@ -692,5 +794,5 @@
     int rcSetParam = av_set_parameters(mpFormatContext, 0);
     AssertReturn(rcSetParam >= 0, E_UNEXPECTED);
-#if 1 /* bird: This works for me on the mac, please review & test elsewhere. */
+# if 1 /* bird: This works for me on the mac, please review & test elsewhere. */
     /* Fill in any uninitialized parameters like opt_output_file in ffpmeg.c does.
        This fixes most of the buffer underflow warnings:
@@ -700,5 +802,5 @@
     if (!mpFormatContext->max_delay)
         mpFormatContext->max_delay = (int)(0.7 * AV_TIME_BASE);
-#endif
+# endif
     return S_OK;
 }
@@ -722,5 +824,5 @@
     return S_OK;
 }
-
+#endif
 
 /**
@@ -734,4 +836,32 @@
 HRESULT FFmpegFB::open_codec()
 {
+#ifdef VBOX_WITH_VPX
+	vpx_codec_err_t      res;
+    /* Populate encoder configuration */
+    if ((res = vpx_codec_enc_config_default(interface, &mVpxConfig, 0)))
+	{
+		LogFlow(("Failed to configure codec \n"));
+        AssertReturn(res == 0, E_UNEXPECTED);
+	}
+
+    mVpxConfig.rc_target_bitrate = 512;
+    mVpxConfig.g_w = mFrameWidth;
+    mVpxConfig.g_h = mFrameHeight;
+    mVpxConfig.g_timebase.den = 30;
+    mVpxConfig.g_timebase.num = 1;
+	mVpxConfig.g_threads = 8;
+
+    vpx_rational ebmlFPS = mVpxConfig.g_timebase;
+    struct vpx_rational arg_framerate = {30, 1};
+    Ebml_WriteWebMFileHeader(&ebml, &mVpxConfig, &arg_framerate);
+    mDuration = (float)arg_framerate.den / (float)arg_framerate.num * 1000;
+
+    /* Initialize codec */
+    if (vpx_codec_enc_init(&mVpxCodec, interface, &mVpxConfig, 0))
+    {
+        LogFlow(("Failed to initialize encoder"));
+        AssertReturn(res == 0, E_UNEXPECTED);
+    }
+#else
     Assert(mpFormatContext != 0);
     Assert(mpStream != 0);
@@ -740,5 +870,5 @@
     AssertReturn(pCodecContext != 0, E_UNEXPECTED);
     AVCodec *pCodec = avcodec_find_encoder(pOutFormat->video_codec);
-#ifdef VBOX_SHOW_AVAILABLE_FORMATS
+# ifdef VBOX_SHOW_AVAILABLE_FORMATS
     if (!pCodec)
     {
@@ -747,5 +877,5 @@
         list_formats();
     }
-#endif
+# endif
     AssertReturn(pCodec != 0, E_UNEXPECTED);
     pCodecContext->codec_id = pOutFormat->video_codec;
@@ -768,4 +898,5 @@
     int rcOpenCodec = avcodec_open(pCodecContext, pCodec);
     AssertReturn(rcOpenCodec >= 0, E_UNEXPECTED);
+#endif
     return S_OK;
 }
@@ -782,4 +913,15 @@
 HRESULT FFmpegFB::open_output_file()
 {
+#ifdef VBOX_WITH_VPX
+    char szFileName[RTPATH_MAX];
+    strcpy(szFileName, com::Utf8Str(mFileName).c_str());
+	ebml.stream = fopen(szFileName, "wb");
+	if (!ebml.stream)
+	{
+		LogFlow(("Failed to open the output File \n"));
+        return E_FAIL;
+	}
+	return S_OK;
+#else
     char szFileName[RTPATH_MAX];
     Assert(mpFormatContext);
@@ -791,4 +933,5 @@
     mfUrlOpen = true;
     av_write_header(mpFormatContext);
+#endif
     return S_OK;
 }
@@ -891,4 +1034,21 @@
     switch (mFFMPEGPixelFormat)
     {
+#ifdef VBOX_WITH_VPX
+        case VPX_IMG_FMT_RGB32:
+            if (!FFmpegWriteYUV420p<FFmpegBGRA32Iter>(mFrameWidth, mFrameHeight,
+                                                      mYUVBuffer, mTempRGBBuffer))
+                return E_UNEXPECTED;
+            break;
+        case VPX_IMG_FMT_RGB24:
+            if (!FFmpegWriteYUV420p<FFmpegBGR24Iter>(mFrameWidth, mFrameHeight,
+                                                     mYUVBuffer, mTempRGBBuffer))
+                return E_UNEXPECTED;
+            break;
+        case VPX_IMG_FMT_RGB565:
+            if (!FFmpegWriteYUV420p<FFmpegBGR565Iter>(mFrameWidth, mFrameHeight,
+                                                      mYUVBuffer, mTempRGBBuffer))
+                return E_UNEXPECTED;
+            break;
+#else
         case PIX_FMT_RGBA32:
             if (!FFmpegWriteYUV420p<FFmpegBGRA32Iter>(mFrameWidth, mFrameHeight,
@@ -906,4 +1066,6 @@
                 return E_UNEXPECTED;
             break;
+
+#endif
         default:
             return E_UNEXPECTED;
@@ -912,5 +1074,4 @@
 }
 
-
 /**
  * Encode the YUV framebuffer as an MPEG frame and write it to the file.
@@ -920,5 +1081,5 @@
 HRESULT FFmpegFB::do_encoding_and_write()
 {
-    AVCodecContext *pContext = mpStream->codec;
+
 
     /* A hack: ffmpeg mpeg2 only writes a frame if something has
@@ -930,4 +1091,47 @@
         mYUVBuffer[0] &= 0xfe;
     mToggle = !mToggle;
+
+#ifdef VBOX_WITH_VPX
+    vpx_image_t          VpxRawImage;
+    vpx_codec_err_t      res;
+    const vpx_codec_cx_pkt_t *pkt;
+    vpx_codec_iter_t iter = NULL;
+
+    if (mFrameWidth < 16 || mFrameWidth%2 || mFrameHeight <16 || mFrameHeight%2)
+        LogFlow(("Invalid resolution: %ldx%ld", mFrameWidth, mFrameHeight));
+
+    if (!vpx_img_alloc(&VpxRawImage, VPX_IMG_FMT_YV12, mFrameWidth, mFrameHeight, 1))
+    {
+        LogFlow(("Faile tod allocate image", mFrameWidth, mFrameHeight));
+        return E_OUTOFMEMORY;
+    }
+
+    if (mYUVBuffer != NULL)
+    {
+		AssertReturn(VpxRawImage.w*VpxRawImage.h*3/2 <= sizeof(mYUVFrameSize), E_UNEXPECTED);
+		memcpy(VpxRawImage.planes[0], (uint8_t *)mYUVBuffer, VpxRawImage.w*VpxRawImage.h*3/2);
+    }
+
+	if ((res = vpx_codec_encode(&mVpxCodec, &VpxRawImage , mFrameCount,
+                  mDuration, 0, VPX_DL_REALTIME)))
+	{
+        LogFlow(("Failed to encode: %s\n", vpx_codec_err_to_string(res)));
+		AssertReturn(res != 0, E_UNEXPECTED);
+
+	}
+    while ((pkt = vpx_codec_get_cx_data(&mVpxCodec, &iter)))
+    {
+        switch (pkt->kind)
+        {
+            case VPX_CODEC_CX_FRAME_PKT:
+                Ebml_WriteWebMBlock(&ebml, &mVpxConfig, pkt);
+                break;
+            default:
+                break;
+        }
+   }
+   mFrameCount++;
+#else
+    AVCodecContext *pContext = mpStream->codec;
     int cSize = avcodec_encode_video(pContext, mOutBuf, mYUVFrameSize * 2,
                                   mFrame);
@@ -953,8 +1157,9 @@
         AssertReturn(rcWriteFrame == 0, E_UNEXPECTED);
     }
-    return S_OK;
-}
-
-
+#endif
+    return S_OK;
+}
+
+#ifndef VBOX_WITH_VPX
 /**
  * Capture the current (i.e. the last) frame as a PNG file with the
@@ -1063,5 +1268,5 @@
     return errorCode;
 }
-
+#endif
 
 #ifdef VBOX_WITH_XPCOM
Index: /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.h	(revision 41952)
+++ /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.h	(revision 41953)
@@ -21,5 +21,5 @@
 
 #include <VBox/com/VirtualBox.h>
-
+#include "EbmlWriter.h"
 #include <iprt/uuid.h>
 
@@ -30,14 +30,25 @@
 #include <iprt/critsect.h>
 
-#ifdef DEBUG
-# define VBOX_DEBUG_FF DEBUG
-# include <avcodec.h>
-# include <avformat.h>
-# undef  DEBUG
-# define DEBUG VBOX_DEBUG_FF
-#else /* DEBUG not defined */
-# include <avcodec.h>
-# include <avformat.h>
-#endif /* DEBUG not defined */
+#ifdef VBOX_WITH_VPX
+#include <stdarg.h>
+#include <string.h>
+#define VPX_CODEC_DISABLE_COMPAT 1
+#include <vp8cx.h>
+#include <vpx_image.h>
+#include <vpx_mem.h>
+#define interface (vpx_codec_vp8_cx())
+#else
+# ifdef DEBUG
+#  define VBOX_DEBUG_FF DEBUG
+#  include <avcodec.h>
+#  include <avformat.h>
+#  undef  DEBUG
+#  define DEBUG VBOX_DEBUG_FF
+# else /* DEBUG not defined */
+#  include <avcodec.h>
+#  include <avformat.h>
+# endif /* DEBUG not defined */
+#endif
+
 
 class FFmpegFB : VBOX_SCRIPTABLE_IMPL(IFramebuffer)
@@ -89,6 +100,26 @@
 
     STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
-
-private:
+public:
+private:
+#ifdef VBOX_WITH_VPX
+	EbmlGlobal ebml;
+	vpx_codec_ctx_t      mVpxCodec;
+    vpx_codec_enc_cfg_t  mVpxConfig;
+	FILE * mOutputFile;
+	unsigned long mDuration;
+	uint32_t  mFrameCount;
+
+#else
+    /** Pointer to ffmpeg's format information context */
+    AVFormatContext *mpFormatContext;
+    /** ffmpeg context containing information about the stream */
+    AVStream *mpStream;
+    /** Information for ffmpeg describing the current frame */
+    AVFrame *mFrame;
+
+	HRESULT setup_library();
+    HRESULT setup_output_format();
+    HRESULT list_formats();
+#endif
     /** true if url_fopen actually succeeded */
     bool mfUrlOpen;
@@ -131,10 +162,4 @@
     /** time at which the last "real" frame was created */
     int64_t mLastTime;
-    /** Pointer to ffmpeg's format information context */
-    AVFormatContext *mpFormatContext;
-    /** ffmpeg context containing information about the stream */
-    AVStream *mpStream;
-    /** Information for ffmpeg describing the current frame */
-    AVFrame *mFrame;
     /** ffmpeg pixel format of guest framebuffer */
     int mFFMPEGPixelFormat;
@@ -147,7 +172,5 @@
     bool mToggle;
 
-    HRESULT setup_library();
-    HRESULT setup_output_format();
-    HRESULT list_formats();
+
     HRESULT open_codec();
     HRESULT open_output_file();
Index: /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/Makefile.kmk	(revision 41952)
+++ /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/Makefile.kmk	(revision 41953)
@@ -21,6 +21,10 @@
 DLLS += VBoxFFmpegFB
 VBoxFFmpegFB_TEMPLATE        = VBOXMAINCLIENTDLL
-VBoxFFmpegFB_SDKS            = VBOX_FFMPEG VBOX_LIBPNG VBOX_ZLIB
-VBoxFFmpegFB_SOURCES         = FFmpegFB.cpp
+#VBoxFFmpegFB_DEFS      += \
+				 VBOX_WITH_VPX  
+VBoxFFmpegFB_SDKS            = VBOX_FFMPEG VBOX_LIBPNG VBOX_ZLIB VBOX_VPX
+VBoxFFmpegFB_SOURCES         +=  \
+							FFmpegFB.cpp \
+							EbmlWriter.cpp
 VBoxFFmpegFB_CXXFLAGS.linux += -fPIC
 
