VirtualBox

source: vbox/trunk/src/VBox/Main/include/RecordingStream.h@ 106956

Last change on this file since 106956 was 106061, checked in by vboxsync, 5 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1/* $Id: RecordingStream.h 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * Recording stream code header.
4 */
5
6/*
7 * Copyright (C) 2012-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef MAIN_INCLUDED_RecordingStream_h
29#define MAIN_INCLUDED_RecordingStream_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include <map>
35#include <vector>
36
37#include <iprt/critsect.h>
38
39#include "RecordingInternals.h"
40
41class WebMWriter;
42class RecordingContext;
43
44/** Structure for queuing all blocks bound to a single timecode.
45 * This can happen if multiple tracks are being involved. */
46struct RecordingBlocks
47{
48 virtual ~RecordingBlocks()
49 {
50 Clear();
51 }
52
53 /**
54 * Resets a recording block list by removing (destroying)
55 * all current elements.
56 */
57 void Clear()
58 {
59 while (!List.empty())
60 {
61 RecordingBlock *pBlock = List.front();
62 List.pop_front();
63 delete pBlock;
64 }
65
66 Assert(List.size() == 0);
67 }
68
69 /** The actual block list for this timecode. */
70 RecordingBlockList List;
71};
72
73/** A block map containing all currently queued blocks.
74 * The key specifies a unique timecode, whereas the value
75 * is a list of blocks which all correlate to the same key (timecode). */
76typedef std::map<uint64_t, RecordingBlocks *> RecordingBlockMap;
77
78/**
79 * Structure for holding a set of recording (data) blocks.
80 */
81struct RecordingBlockSet
82{
83 virtual ~RecordingBlockSet()
84 {
85 Clear();
86 }
87
88 /**
89 * Resets a recording block set by removing (destroying)
90 * all current elements.
91 */
92 void Clear(void)
93 {
94 RecordingBlockMap::iterator it = Map.begin();
95 while (it != Map.end())
96 {
97 it->second->Clear();
98 delete it->second;
99 Map.erase(it);
100 it = Map.begin();
101 }
102
103 Assert(Map.size() == 0);
104 }
105
106 /** Timestamp (in ms) when this set was last processed. */
107 uint64_t tsLastProcessedMs;
108 /** All blocks related to this block set. */
109 RecordingBlockMap Map;
110};
111
112/**
113 * Class for managing a recording stream.
114 *
115 * A recording stream represents one entity to record (e.g. on screen / monitor),
116 * so there is a 1:1 mapping (stream <-> monitors).
117 */
118class RecordingStream
119{
120public:
121
122 RecordingStream(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreen &Settings);
123
124 virtual ~RecordingStream(void);
125
126public:
127
128 int Init(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreen &Settings);
129 int Uninit(void);
130
131 int ThreadMain(int rcWait, uint64_t msTimestamp, RecordingBlockMap &commonBlocks);
132 int SendAudioFrame(const void *pvData, size_t cbData, uint64_t msTimestamp);
133 int SendCursorPos(uint8_t idCursor, PRECORDINGPOS pPos, uint64_t msTimestamp);
134 int SendCursorShape(uint8_t idCursor, PRECORDINGVIDEOFRAME pShape, uint64_t msTimestamp);
135 int SendVideoFrame(PRECORDINGVIDEOFRAME pFrame, uint64_t msTimestamp);
136 int SendScreenChange(PRECORDINGSURFACEINFO pInfo, uint64_t msTimestamp, bool fForce = false);
137
138 const settings::RecordingScreen &GetConfig(void) const;
139 uint16_t GetID(void) const { return this->m_uScreenID; };
140#ifdef VBOX_WITH_AUDIO_RECORDING
141 PRECORDINGCODEC GetAudioCodec(void) { return this->m_pCodecAudio; };
142#endif
143 PRECORDINGCODEC GetVideoCodec(void) { return &this->m_CodecVideo; };
144
145 bool IsLimitReached(uint64_t msTimestamp) const;
146 bool IsFeatureEnabled(RecordingFeature_T enmFeature) const;
147 bool NeedsUpdate(uint64_t msTimestamp) const;
148
149public:
150
151 static DECLCALLBACK(int) codecWriteDataCallback(PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags, void *pvUser);
152
153protected:
154
155 int open(const settings::RecordingScreen &screenSettings);
156 int close(void);
157
158 int initInternal(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreen &screenSettings);
159 int uninitInternal(void);
160
161 int initVideo(const settings::RecordingScreen &screenSettings);
162 int unitVideo(void);
163
164 bool isLimitReachedInternal(uint64_t msTimestamp) const;
165 int iterateInternal(uint64_t msTimestamp);
166
167 int addFrame(PRECORDINGFRAME pFrame, uint64_t msTimestamp);
168 int process(const RecordingBlockSet &streamBlocks, RecordingBlockMap &commonBlocks);
169 int codecWriteToWebM(PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags);
170
171 void lock(void);
172 void unlock(void);
173
174protected:
175
176 /**
177 * Enumeration for a recording stream state.
178 */
179 enum RECORDINGSTREAMSTATE
180 {
181 /** Stream not initialized. */
182 RECORDINGSTREAMSTATE_UNINITIALIZED = 0,
183 /** Stream was initialized. */
184 RECORDINGSTREAMSTATE_INITIALIZED = 1,
185 /** The usual 32-bit hack. */
186 RECORDINGSTREAMSTATE_32BIT_HACK = 0x7fffffff
187 };
188
189 /** Recording context this stream is associated to. */
190 RecordingContext *m_pCtx;
191 /** The current state. */
192 RECORDINGSTREAMSTATE m_enmState;
193 struct
194 {
195 /** File handle to use for writing. */
196 RTFILE m_hFile;
197 /** Pointer to WebM writer instance being used. */
198 WebMWriter *m_pWEBM;
199 } File;
200 bool m_fEnabled;
201 /** Track number of audio stream.
202 * Set to UINT8_MAX if not being used. */
203 uint8_t m_uTrackAudio;
204 /** Track number of video stream.
205 * Set to UINT8_MAX if not being used. */
206 uint8_t m_uTrackVideo;
207 /** Screen ID. */
208 uint16_t m_uScreenID;
209 /** Critical section to serialize access. */
210 RTCRITSECT m_CritSect;
211 /** Timestamp (in ms) of when recording has been started. */
212 uint64_t m_tsStartMs;
213#ifdef VBOX_WITH_AUDIO_RECORDING
214 /** Pointer to audio codec instance data to use.
215 *
216 * We multiplex audio data from the recording context to all streams,
217 * to avoid encoding the same audio data for each stream. We ASSUME that
218 * all audio data of a VM will be the same for each stream at a given
219 * point in time.
220 *
221 * Might be NULL if not being used. */
222 PRECORDINGCODEC m_pCodecAudio;
223#endif /* VBOX_WITH_AUDIO_RECORDING */
224 /** Video codec instance data to use. */
225 RECORDINGCODEC m_CodecVideo;
226 /** Screen settings to use. */
227 settings::RecordingScreen
228 m_ScreenSettings;
229 /** Set of recording (data) blocks for this stream. */
230 RecordingBlockSet m_Blocks;
231};
232
233/** Vector of recording streams. */
234typedef std::vector <RecordingStream *> RecordingStreams;
235
236#endif /* !MAIN_INCLUDED_RecordingStream_h */
237
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette