summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/include/RecordingStream.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Main/include/RecordingStream.h
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Main/include/RecordingStream.h')
-rw-r--r--src/VBox/Main/include/RecordingStream.h234
1 files changed, 234 insertions, 0 deletions
diff --git a/src/VBox/Main/include/RecordingStream.h b/src/VBox/Main/include/RecordingStream.h
new file mode 100644
index 00000000..7d9dc48d
--- /dev/null
+++ b/src/VBox/Main/include/RecordingStream.h
@@ -0,0 +1,234 @@
+/* $Id: RecordingStream.h $ */
+/** @file
+ * Recording stream code header.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_RecordingStream_h
+#define MAIN_INCLUDED_RecordingStream_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <map>
+#include <vector>
+
+#include <iprt/critsect.h>
+
+#include "RecordingInternals.h"
+
+class WebMWriter;
+class RecordingContext;
+
+/** Structure for queuing all blocks bound to a single timecode.
+ * This can happen if multiple tracks are being involved. */
+struct RecordingBlocks
+{
+ virtual ~RecordingBlocks()
+ {
+ Clear();
+ }
+
+ /**
+ * Resets a recording block list by removing (destroying)
+ * all current elements.
+ */
+ void Clear()
+ {
+ while (!List.empty())
+ {
+ RecordingBlock *pBlock = List.front();
+ List.pop_front();
+ delete pBlock;
+ }
+
+ Assert(List.size() == 0);
+ }
+
+ /** The actual block list for this timecode. */
+ RecordingBlockList List;
+};
+
+/** A block map containing all currently queued blocks.
+ * The key specifies a unique timecode, whereas the value
+ * is a list of blocks which all correlate to the same key (timecode). */
+typedef std::map<uint64_t, RecordingBlocks *> RecordingBlockMap;
+
+/**
+ * Structure for holding a set of recording (data) blocks.
+ */
+struct RecordingBlockSet
+{
+ virtual ~RecordingBlockSet()
+ {
+ Clear();
+ }
+
+ /**
+ * Resets a recording block set by removing (destroying)
+ * all current elements.
+ */
+ void Clear(void)
+ {
+ RecordingBlockMap::iterator it = Map.begin();
+ while (it != Map.end())
+ {
+ it->second->Clear();
+ delete it->second;
+ Map.erase(it);
+ it = Map.begin();
+ }
+
+ Assert(Map.size() == 0);
+ }
+
+ /** Timestamp (in ms) when this set was last processed. */
+ uint64_t tsLastProcessedMs;
+ /** All blocks related to this block set. */
+ RecordingBlockMap Map;
+};
+
+/**
+ * Class for managing a recording stream.
+ *
+ * A recording stream represents one entity to record (e.g. on screen / monitor),
+ * so there is a 1:1 mapping (stream <-> monitors).
+ */
+class RecordingStream
+{
+public:
+
+ RecordingStream(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreenSettings &Settings);
+
+ virtual ~RecordingStream(void);
+
+public:
+
+ int Init(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreenSettings &Settings);
+ int Uninit(void);
+
+ int Process(RecordingBlockMap &mapBlocksCommon);
+ int SendAudioFrame(const void *pvData, size_t cbData, uint64_t msTimestamp);
+ int SendVideoFrame(uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP, uint32_t uBytesPerLine,
+ uint32_t uSrcWidth, uint32_t uSrcHeight, uint8_t *puSrcData, uint64_t msTimestamp);
+
+ const settings::RecordingScreenSettings &GetConfig(void) const;
+ uint16_t GetID(void) const { return this->m_uScreenID; };
+#ifdef VBOX_WITH_AUDIO_RECORDING
+ PRECORDINGCODEC GetAudioCodec(void) { return this->m_pCodecAudio; };
+#endif
+ PRECORDINGCODEC GetVideoCodec(void) { return &this->m_CodecVideo; };
+
+ bool IsLimitReached(uint64_t msTimestamp) const;
+ bool IsReady(void) const;
+ bool NeedsUpdate(uint64_t msTimestamp) const;
+
+public:
+
+ static DECLCALLBACK(int) codecWriteDataCallback(PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags, void *pvUser);
+
+protected:
+
+ int open(const settings::RecordingScreenSettings &screenSettings);
+ int close(void);
+
+ int initInternal(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreenSettings &screenSettings);
+ int uninitInternal(void);
+
+ int initVideo(const settings::RecordingScreenSettings &screenSettings);
+ int unitVideo(void);
+
+ bool isLimitReachedInternal(uint64_t msTimestamp) const;
+ int iterateInternal(uint64_t msTimestamp);
+
+ int codecWriteToWebM(PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags);
+
+ void lock(void);
+ void unlock(void);
+
+protected:
+
+ /**
+ * Enumeration for a recording stream state.
+ */
+ enum RECORDINGSTREAMSTATE
+ {
+ /** Stream not initialized. */
+ RECORDINGSTREAMSTATE_UNINITIALIZED = 0,
+ /** Stream was initialized. */
+ RECORDINGSTREAMSTATE_INITIALIZED = 1,
+ /** The usual 32-bit hack. */
+ RECORDINGSTREAMSTATE_32BIT_HACK = 0x7fffffff
+ };
+
+ /** Recording context this stream is associated to. */
+ RecordingContext *m_pCtx;
+ /** The current state. */
+ RECORDINGSTREAMSTATE m_enmState;
+ struct
+ {
+ /** File handle to use for writing. */
+ RTFILE m_hFile;
+ /** Pointer to WebM writer instance being used. */
+ WebMWriter *m_pWEBM;
+ } File;
+ bool m_fEnabled;
+ /** Track number of audio stream.
+ * Set to UINT8_MAX if not being used. */
+ uint8_t m_uTrackAudio;
+ /** Track number of video stream.
+ * Set to UINT8_MAX if not being used. */
+ uint8_t m_uTrackVideo;
+ /** Screen ID. */
+ uint16_t m_uScreenID;
+ /** Critical section to serialize access. */
+ RTCRITSECT m_CritSect;
+ /** Timestamp (in ms) of when recording has been started. */
+ uint64_t m_tsStartMs;
+#ifdef VBOX_WITH_AUDIO_RECORDING
+ /** Pointer to audio codec instance data to use.
+ *
+ * We multiplex audio data from the recording context to all streams,
+ * to avoid encoding the same audio data for each stream. We ASSUME that
+ * all audio data of a VM will be the same for each stream at a given
+ * point in time.
+ *
+ * Might be NULL if not being used. */
+ PRECORDINGCODEC m_pCodecAudio;
+#endif /* VBOX_WITH_AUDIO_RECORDING */
+ /** Video codec instance data to use. */
+ RECORDINGCODEC m_CodecVideo;
+ /** Screen settings to use. */
+ settings::RecordingScreenSettings
+ m_ScreenSettings;
+ /** Common set of recording (data) blocks, needed for
+ * multiplexing to all recording streams. */
+ RecordingBlockSet m_Blocks;
+};
+
+/** Vector of recording streams. */
+typedef std::vector <RecordingStream *> RecordingStreams;
+
+#endif /* !MAIN_INCLUDED_RecordingStream_h */
+