Index: trunk/src/VBox/Main/src-client/DisplayImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/DisplayImpl.cpp	(revision 45950)
+++ trunk/src/VBox/Main/src-client/DisplayImpl.cpp	(revision 45956)
@@ -49,4 +49,5 @@
 
 #ifdef VBOX_WITH_VPX
+# include <iprt/path.h>
 # include "VideoRec.h"
 #endif
@@ -528,6 +529,5 @@
 
 #ifdef VBOX_WITH_VPX
-    if (mpVideoRecCtx)
-        VideoRecContextClose(mpVideoRecCtx);
+    VideoRecContextClose(mpVideoRecCtx);
 #endif
 }
@@ -3318,5 +3318,5 @@
                                               pDrv->IConnector.cy, pDrv->IConnector.pu8Data, u64Now);
                 }
-                if (rc == VERR_TRY_AGAIN)
+                if (rc == VINF_TRY_AGAIN)
                     break;
             }
@@ -4379,6 +4379,21 @@
         for (unsigned uScreen = 0; uScreen < pDisplay->mcMonitors; uScreen++)
         {
+            char *pszAbsPath = RTPathAbsDup(com::Utf8Str(strFile).c_str());
+            char *pszExt = RTPathExt(pszAbsPath);
+            if (pszExt)
+                pszExt = RTStrDup(pszExt);
+            RTPathStripExt(pszAbsPath);
+            if (!pszAbsPath)
+                rc = VERR_INVALID_PARAMETER;
+            if (!pszExt)
+                pszExt = RTStrDup(".webm");
             char *pszName = NULL;
-            rc = RTStrAPrintf(&pszName, "%s-%u", com::Utf8Str(strFile).c_str(), uScreen);
+            if (RT_SUCCESS(rc))
+            {
+                if (pDisplay->mcMonitors > 1)
+                    rc = RTStrAPrintf(&pszName, "%s-%u%s", pszAbsPath, uScreen, pszExt);
+                else
+                    rc = RTStrAPrintf(&pszName, "%s%s", pszAbsPath, pszExt);
+            }
             if (RT_SUCCESS(rc))
                 rc = VideoRecStrmInit(pDisplay->mpVideoRecCtx, uScreen,
@@ -4389,6 +4404,7 @@
             else
                 LogRel(("Failed to initialize video recording context #%u (%Rrc)!\n", uScreen, rc));
-            if (pszName)
-                RTStrFree(pszName);
+            RTStrFree(pszName);
+            RTStrFree(pszExt);
+            RTStrFree(pszAbsPath);
         }
     }
Index: trunk/src/VBox/Main/src-client/VideoRec.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/VideoRec.cpp	(revision 45950)
+++ trunk/src/VBox/Main/src-client/VideoRec.cpp	(revision 45956)
@@ -78,8 +78,4 @@
     /* true if video recording is enabled */
     bool                fEnabled;
-    /* worker thread */
-    RTTHREAD            Thread;
-    /* see VIDREC_xxx */
-    uint32_t            u32State;
     /* true if the RGB buffer is filled */
     bool                fRgbFilled;
@@ -103,5 +99,5 @@
     RTTHREAD            Thread;
     /* see VIDREC_xxx */
-    uint32_t            u32State;
+    uint32_t            uState;
     /* number of stream contexts */
     uint32_t            cScreens;
@@ -383,5 +379,5 @@
  * RGB/YUV conversion and encoding.
  */
-DECLCALLBACK(int) videoRecThread(RTTHREAD ThreadSelf, void *pvUser)
+static DECLCALLBACK(int) videoRecThread(RTTHREAD Thread, void *pvUser)
 {
     PVIDEORECCONTEXT pCtx = (PVIDEORECCONTEXT)pvUser;
@@ -391,5 +387,5 @@
         AssertRCBreak(rc);
 
-        if (ASMAtomicReadU32(&pCtx->u32State) == VIDREC_TERMINATING)
+        if (ASMAtomicReadU32(&pCtx->uState) == VIDREC_TERMINATING)
             break;
         for (unsigned uScreen = 0; uScreen < pCtx->cScreens; uScreen++)
@@ -403,11 +399,17 @@
                     rc = videoRecEncodeAndWrite(pStrm);
                 if (RT_FAILURE(rc))
-                    LogRel(("Error %Rrc encoding video frame\n", rc));
+                {
+                    static unsigned cErrors = 100;
+                    if (cErrors > 0)
+                    {
+                        LogRel(("Error %Rrc encoding / writing video frame\n", rc));
+                        cErrors--;
+                    }
+                }
             }
         }
     }
 
-    ASMAtomicWriteU32(&pCtx->u32State, VIDREC_TERMINATED);
-    RTThreadUserSignal(ThreadSelf);
+    ASMAtomicWriteU32(&pCtx->uState, VIDREC_TERMINATED);
     return VINF_SUCCESS;
 }
@@ -429,12 +431,13 @@
     for (unsigned uScreen = 0; uScreen < cScreens; uScreen++)
         pCtx->Strm[uScreen].Ebml.last_pts_ms = -1;
-    
+
     int rc = RTSemEventCreate(&pCtx->WaitEvent);
     AssertRCReturn(rc, rc);
 
     rc = RTThreadCreate(&pCtx->Thread, videoRecThread, (void*)pCtx, 0,
-                        RTTHREADTYPE_MAIN_WORKER, 0, "VideoRec");
+                        RTTHREADTYPE_MAIN_WORKER, RTTHREADFLAGS_WAITABLE, "VideoRec");
     AssertRCReturn(rc, rc);
 
+    ASMAtomicWriteU32(&pCtx->uState, VIDREC_INITIALIZED);
     return VINF_SUCCESS;
 }
@@ -466,5 +469,5 @@
     if (RT_FAILURE(rc))
     {
-        LogFlow(("Failed to open the output File\n"));
+        LogFlow(("Failed to open the video capture output File (%Rrc)\n", rc));
         return rc;
     }
@@ -474,5 +477,5 @@
     {
         LogFlow(("Failed to configure codec\n", vpx_codec_err_to_string(rcv)));
-        return rc;
+        return VERR_INVALID_PARAMETER;
     }
 
@@ -490,5 +493,5 @@
     pStrm->uDelay = 1000 / uFps;
 
-    struct vpx_rational arg_framerate = {30, 1};
+    struct vpx_rational arg_framerate = { 30, 1 };
     rc = Ebml_WriteWebMFileHeader(&pStrm->Ebml, &pStrm->VpxConfig, &arg_framerate);
     AssertRCReturn(rc, rc);
@@ -498,9 +501,7 @@
     if (rcv != VPX_CODEC_OK)
     {
-        LogFlow(("Failed to initialize encoder %s", vpx_codec_err_to_string(rcv)));
-        return VERR_GENERAL_FAILURE;
-    }
-
-    ASMAtomicWriteU32(&pStrm->u32State, VIDREC_INITIALIZED);
+        LogFlow(("Failed to initialize VP8 encoder %s", vpx_codec_err_to_string(rcv)));
+        return VERR_INVALID_PARAMETER;
+    }
 
     if (!vpx_img_alloc(&pStrm->VpxRawImage, VPX_IMG_FMT_I420, uWidth, uHeight, 1))
@@ -522,14 +523,14 @@
 void VideoRecContextClose(PVIDEORECCONTEXT pCtx)
 {
-    if (ASMAtomicReadU32(&pCtx->u32State) == VIDREC_UNINITIALIZED)
+    if (!pCtx)
         return;
 
-    if (pCtx->fEnabled)
-    {
-        ASMAtomicWriteU32(&pCtx->u32State, VIDREC_TERMINATING);
-        RTSemEventSignal(pCtx->WaitEvent);
-        RTThreadUserWait(pCtx->Thread, 10000);
-        RTSemEventDestroy(pCtx->WaitEvent);
-    }
+    if (ASMAtomicReadU32(&pCtx->uState) != VIDREC_INITIALIZED)
+        return;
+
+    ASMAtomicWriteU32(&pCtx->uState, VIDREC_TERMINATING);
+    RTSemEventSignal(pCtx->WaitEvent);
+    RTThreadWait(pCtx->Thread, 10000, NULL);
+    RTSemEventDestroy(pCtx->WaitEvent);
 
     for (unsigned uScreen = 0; uScreen < pCtx->cScreens; uScreen++)
@@ -549,8 +550,11 @@
         }
         vpx_img_free(&pStrm->VpxRawImage);
-        vpx_codec_destroy(&pStrm->VpxCodec);
+        vpx_codec_err_t rcv = vpx_codec_destroy(&pStrm->VpxCodec);
+        Assert(rcv == VPX_CODEC_OK);
         RTMemFree(pStrm->pu8RgbBuf);
         pStrm->pu8RgbBuf = NULL;
     }
+
+    ASMAtomicWriteU32(&pCtx->uState, VIDREC_UNINITIALIZED);
 }
 
@@ -682,13 +686,15 @@
     AssertReturn(uSourceHeight, VERR_INVALID_PARAMETER);
     AssertReturn(uScreen < pCtx->cScreens, VERR_INVALID_PARAMETER);
+    AssertReturn(pCtx->uState == VIDREC_INITIALIZED, VERR_INVALID_STATE);
 
     PVIDEORECSTREAM pStrm = &pCtx->Strm[uScreen];
 
     if (u64TimeStamp < pStrm->u64LastTimeStamp + pStrm->uDelay)
-        return VINF_TRY_AGAIN;
+        return VINF_TRY_AGAIN; /* respect maximum frames per second */
+
+    if (ASMAtomicReadBool(&pStrm->fRgbFilled))
+        return VERR_TRY_AGAIN; /* previous frame not yet encoded */
+
     pStrm->u64LastTimeStamp = u64TimeStamp;
-
-    if (ASMAtomicReadBool(&pStrm->fRgbFilled))
-        return VERR_TRY_AGAIN;
 
     int xDiff = ((int)pStrm->uTargetWidth - (int)uSourceWidth) / 2;
