Index: /trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp	(revision 68337)
+++ /trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp	(revision 68338)
@@ -123,18 +123,9 @@
     /** The encoding rate to use. */
     uint32_t                uHz;
-    /** Duration of the frame in samples (per channel).
-     *
-     *  For Opus, valid frame size are:
-     *  ms           Frame size
-     *  2.5          120
-     *  5            240
-     *  10           480
-     *  20 (Default) 960
-     *  40           1920
-     *  60           2880
-     */
     /** Number of audio channels to encode.
      *  Currently we only supported stereo (2) channels. */
     uint8_t                 cChannels;
+    /** Bits per sample. */
+    uint8_t                 cBits;
     /** The codec's bitrate. 0 if not used / cannot be specified. */
     uint32_t                uBitrate;
@@ -156,8 +147,16 @@
             /** Encoder we're going to use. */
             OpusEncoder    *pEnc;
-            /** Number of samples per frame. */
-            uint32_t        csFrame;
-            /** The maximum frame size (in samples) we can handle. */
-            uint32_t        csFrameMax;
+            /** Time (in ms) an (encoded) frame takes.
+             *
+             *  For Opus, valid frame size are:
+             *  ms           Frame size
+             *  2.5          120
+             *  5            240
+             *  10           480
+             *  20 (Default) 960
+             *  40           1920
+             *  60           2880
+             */
+            uint32_t        msFrame;
         } Opus;
 #endif /* VBOX_WITH_LIBOPUS */
@@ -182,5 +181,5 @@
     /** Container data to use for data processing. */
     AVRECCONTAINER       Con;
-    /** Codec data this stream uses for encoding. */
+    /** Codec data this sink uses for encoding. */
     AVRECCODEC           Codec;
 } AVRECSINK, *PAVRECSINK;
@@ -233,5 +232,8 @@
 static int avRecSinkInit(PDRVAUDIOVIDEOREC pThis, PAVRECSINK pSink, PAVRECCONTAINERPARMS pConParms, PAVRECCODECPARMS pCodecParms)
 {
-    uint32_t uHz = pCodecParms->uHz;
+    uint32_t uHz       = pCodecParms->uHz;
+    uint8_t  cBits     = 16; /** @ŧodo Make this configurable? */
+    uint8_t  cChannels = pCodecParms->cChannels;
+    uint32_t uBitrate  = pCodecParms->uBitrate;
 
     /* Opus only supports certain input sample rates in an efficient manner.
@@ -243,8 +245,14 @@
     else     uHz = 8000;
 
-    OpusEncoder *pEnc = NULL;
+    if (cChannels > 2)
+    {
+        LogRel(("VideoRec: More than 2 (stereo) channels are not supported at the moment\n"));
+        cChannels = 2;
+    }
+
+    LogRel2(("VideoRec: Recording audio in %RU16Hz, %RU8 channels, %RU32 bitrate\n", uHz, cChannels, uBitrate));
 
     int orc;
-    pEnc = opus_encoder_create(pCodecParms->uHz, pCodecParms->cChannels, OPUS_APPLICATION_AUDIO, &orc);
+    OpusEncoder *pEnc = opus_encoder_create(uHz, cChannels, OPUS_APPLICATION_AUDIO, &orc);
     if (orc != OPUS_OK)
     {
@@ -255,13 +263,13 @@
     AssertPtr(pEnc);
 
-    opus_encoder_ctl(pEnc, OPUS_SET_BITRATE(pCodecParms->uBitrate));
+    opus_encoder_ctl(pEnc, OPUS_SET_BITRATE(uBitrate));
     if (orc != OPUS_OK)
     {
-        LogRel(("VideoRec: Audio codec failed to set bitrate (%RU32): %s\n", pCodecParms->uBitrate, opus_strerror(orc)));
+        opus_encoder_destroy(pEnc);
+        pEnc = NULL;
+
+        LogRel(("VideoRec: Audio codec failed to set bitrate (%RU32): %s\n", uBitrate, opus_strerror(orc)));
         return VERR_AUDIO_BACKEND_INIT_FAILED;
     }
-
-    LogRel(("VideoRec: Recording audio in %RU16Hz, %RU8 channels, %RU32 bpS\n",
-            pCodecParms->uHz, pCodecParms->cChannels, pCodecParms->uBitrate / 1000));
 
     int rc;
@@ -281,5 +289,37 @@
             case AVRECCONTAINERTYPE_WEBM:
             {
-                rc = VINF_SUCCESS;
+                /* If we only record audio, create our own WebM writer instance here. */
+                if (!pSink->Con.WebM.pWebM) /* Do we already have our WebM writer instance? */
+                {
+                    char szFile[RTPATH_MAX];
+                    if (RTStrPrintf(szFile, sizeof(szFile), "%s%s",
+                                    VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH, "DrvAudioVideoRec.webm" /** @todo Make this configurable. */))
+                    {
+                        /** @todo Add sink name / number to file name. */
+
+                        LogRel2(("VideoRec: Recording audio to file '%s'\n", szFile));
+
+                        pSink->Con.WebM.pWebM = new WebMWriter();
+                        rc = pSink->Con.WebM.pWebM->Create(szFile,
+                                                           /** @ŧodo Add option to add some suffix if file exists instead of overwriting? */
+                                                           RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE,
+                                                           WebMWriter::AudioCodec_Opus, WebMWriter::VideoCodec_None);
+                        if (RT_SUCCESS(rc))
+                        {
+                            rc = pSink->Con.WebM.pWebM->AddAudioTrack(uHz, cChannels, cBits,
+                                                                      &pSink->Con.WebM.uTrack);
+                            if (RT_FAILURE(rc))
+                                LogRel(("VideoRec: Error creating audio track for file '%s' (%Rrc)\n", szFile, rc));
+                        }
+                        else
+                            LogRel(("VideoRec: Error creating audio file '%s' (%Rrc)\n", szFile, rc));
+                    }
+                    else
+                    {
+                        AssertFailed(); /* Should never happen. */
+                        LogRel(("VideoRec: Error creating audio file path\n"));
+                    }
+                }
+
                 break;
             }
@@ -300,9 +340,10 @@
 
         pSink->Codec.Parms.uHz       = uHz;
-        pSink->Codec.Parms.cChannels = pCodecParms->cChannels;
-        pSink->Codec.Parms.uBitrate  = pCodecParms->uBitrate;
+        pSink->Codec.Parms.cChannels = cChannels;
+        pSink->Codec.Parms.cBits     = cBits;
+        pSink->Codec.Parms.uBitrate  = uBitrate;
 
         pSink->Codec.Opus.pEnc       = pEnc;
-        pSink->Codec.Opus.csFrame    = uHz / 50;
+        pSink->Codec.Opus.msFrame    = 20; /** @todo 20 ms of audio data. Make this configurable? */
 
 #ifdef VBOX_WITH_STATISTICS
@@ -310,8 +351,14 @@
         pSink->Codec.STAM.msEncTotal = 0;
 #endif
-
-        /* Calculate the maximum frame size. */
-        pSink->Codec.Opus.csFrameMax = AVREC_OPUS_HZ_MAX       /* Maximum sample rate Opus can handle */
-                                     * pCodecParms->cChannels; /* Number of channels */
+    }
+    else
+    {
+        if (pEnc)
+        {
+            opus_encoder_destroy(pEnc);
+            pEnc = NULL;
+        }
+
+        LogRel(("VideoRec: Error creating sink (%Rrc)\n", rc));
     }
 
@@ -343,4 +390,7 @@
             if (pSink->Con.WebM.pWebM)
             {
+                LogRel2(("VideoRec: Finished recording audio to file '%s' (%zu bytes)\n",
+                         pSink->Con.WebM.pWebM->GetFileName().c_str(), pSink->Con.WebM.pWebM->GetFileSize()));
+
                 int rc2 = pSink->Con.WebM.pWebM->Close();
                 AssertRC(rc2);
@@ -392,20 +442,10 @@
 
 #ifdef VBOX_WITH_LIBOPUS
-    /* If we only record audio, create our own WebM writer instance here. */
-    if (pSink->Con.Parms.enmType == AVRECCONTAINERTYPE_WEBM)
-    {
-        pSink->Con.WebM.pWebM = new WebMWriter();
-        rc = pSink->Con.WebM.pWebM->Create(VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH "DrvAudioVideoRec.webm", /** @todo Make this configurable. */
-                                           RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE,
-                                           WebMWriter::AudioCodec_Opus, WebMWriter::VideoCodec_None);
-        if (RT_SUCCESS(rc))
-            rc = pSink->Con.WebM.pWebM->AddAudioTrack(pSink->Codec.Parms.uHz, pCfgReq->Props.cChannels, pCfgReq->Props.cBits,
-                                                      &pSink->Con.WebM.uTrack);
-    }
-
-    if (RT_FAILURE(rc))
-        return rc;
-
-    rc = RTCircBufCreate(&pStreamAV->pCircBuf, (pSink->Codec.Opus.csFrame * pSink->Codec.Parms.cChannels) * sizeof(uint16_t));
+    const unsigned cFrames = 2; /** @todo Use the PreRoll param for that? */
+
+    const uint32_t csFrame = pSink->Codec.Parms.uHz / (1000 /* s in ms */ / pSink->Codec.Opus.msFrame);
+    const uint32_t cbFrame = csFrame * pSink->Codec.Parms.cChannels * (pSink->Codec.Parms.cBits / 8 /* Bytes */);
+
+    rc = RTCircBufCreate(&pStreamAV->pCircBuf, cbFrame * cFrames);
     if (RT_SUCCESS(rc))
     {
@@ -494,5 +534,5 @@
 
     AVRECCONTAINERPARMS ContainerParms;
-    ContainerParms.enmType = AVRECCONTAINERTYPE_MAIN_CONSOLE; /** @todo Make this configurable. */
+    ContainerParms.enmType = AVRECCONTAINERTYPE_WEBM; /** @todo Make this configurable. */
 
     AVRECCODECPARMS CodecParms;
@@ -594,6 +634,6 @@
     size_t  cbSrc;
 
-    const uint32_t csFrame = pSink->Codec.Opus.csFrame;
-    const uint32_t cbFrame = PDMAUDIOSTREAMCFG_F2B(pStreamAV->pCfg, csFrame);
+    const uint32_t csFrame = pSink->Codec.Parms.uHz / (1000 /* s in ms */ / pSink->Codec.Opus.msFrame);
+    const uint32_t cbFrame = csFrame * pSink->Codec.Parms.cChannels * (pSink->Codec.Parms.cBits / 8 /* Bytes */);
 
     while (RTCircBufUsed(pCircBuf) >= cbFrame)
Index: /trunk/src/VBox/Main/src-client/EbmlWriter.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/EbmlWriter.cpp	(revision 68337)
+++ /trunk/src/VBox/Main/src-client/EbmlWriter.cpp	(revision 68338)
@@ -583,5 +583,5 @@
 
         pTrack->Audio.uHz     = uHz;
-        pTrack->Audio.csFrame = pTrack->Audio.uHz / 50; /** @todo 20 ms of audio data. Make this configurable? */
+        pTrack->Audio.csFrame = pTrack->Audio.uHz / (1000 /* s in ms */ / 20); /** @todo 20 ms of audio data. Make this configurable? */
 
         OpusPrivData opusPrivData(uHz, cChannels);
@@ -594,5 +594,5 @@
               .serializeData(MkvElem_CodecPrivate,            &opusPrivData, sizeof(opusPrivData))
               .serializeUnsignedInteger(MkvElem_CodecDelay,   0)
-              .serializeUnsignedInteger(MkvElem_SeekPreRoll,  80000000) /* 80ms in ns. */
+              .serializeUnsignedInteger(MkvElem_SeekPreRoll,  80 * 1000000) /* 80ms in ns. */
               .subStart(MkvElem_Audio)
                   .serializeFloat(MkvElem_SamplingFrequency,  (float)uHz)
